hdu 1059 Dividing(多重背包)

和hdu1171差不多吧

359ms:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXN 7
#define MAXM 225001

int aver, num[MAXN];
int f[MAXM];

inline int getMax(int a, int b)
{
    return a > b ? a : b;
}

void ZeroOnePack(int w, int v)
{
    for(int j = aver; j >= w; j--)
    {
        f[j] = getMax(f[j], f[j - w] + v);
    }
}
void CompletePack(int w, int v)
{
    for(int j = w; j <= aver; j++)
    {
        f[j] = getMax(f[j], f[j - w] + v);
    }
}
void MultiplePack(int w, int v, int amount)
{
    if(amount * w >= aver)
    {
        CompletePack(w, v);
        return;
    }
    int k = 1;
    while(k < amount)
    {
        ZeroOnePack(k * w, k * v);
        amount -= k;
        k <<= 1;
    }
    ZeroOnePack(amount * w, amount * v);
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("indata.txt", "r", stdin);
#endif
	int cas = 1;
	while(true)
	{
		int i, sum = 0;
		for(i = 1; i <= 6; i++)
		{
			scanf("%d", &num[i]);
			sum += i * num[i];
		}
		if(!sum) break;
//		printf("sum=%d\n", sum);
		printf("Collection #%d:\n", cas++);
		if(sum & 1)
		{
			printf("Can't be divided.\n\n");
			continue;
		}
		aver = sum >> 1;
		
		memset(f, 0, sizeof(*f) * (aver + 1));
		for(i = 1; i <= 6; i++) MultiplePack(i, i, num[i]);
	//	for(i = 0; i <= aver; i++) printf("%d ", f[i]); printf("\n");		
		
		if(aver == f[aver]) printf("Can be divided.\n\n");
		else printf("Can't be divided.\n\n");
	}
    return 0;
}

posted @ 2010-10-18 23:45  菜到不得鸟  阅读(119)  评论(0)    收藏  举报