POJ 1014 Dividing 多重背包

让物体的重量等于价值,用总价值的一半的包去装这些物品,看其是否能装满

View Code
#include<stdio.h>
#include<string.h>
int dp[120005], a[8];
int max(int a, int b) { return a > b ? a : b;}
int main()
{
    int i, j, cas = 1, n, m;
    while( ~scanf("%d", &a[1]) )
    {    
        int sum = a[1];
        for(i = 2; i <= 6; i++)
        {
            scanf("%d", &a[i]);
            sum += i * a[i];
        }
        if(!sum) break;
        printf("Collection #%d:\n", cas++);
    
        if(sum & 1) { printf("Can't be divided.\n\n");continue; }
        sum >>= 1;
        memset(dp, 0, sizeof(dp));
        for(i = 1; i <= 6; i++)
        {
            if(i * a[i] >= sum)
                for(j = i; j <= sum; j++)
                    dp[j] = max(dp[j], dp[j-i]+i);
            else
            {
                int k = 1;
                while(k < a[i])
                {
                    for(j = sum; j >= i*k; j--)
                        dp[j] = max(dp[j], dp[j-i*k]+i*k);
                    a[i] -= k;
                    k <<= 1;
                }
                for(j = sum; j >= i*a[i]; j--)
                    dp[j] = max(dp[j], dp[j-i*a[i]]+i*a[i]);
            }
            if(dp[sum] == sum) break;
        }
        if(dp[sum] == sum) printf("Can be divided.\n\n");
        else printf("Can't be divided.\n\n");
    }
    return 0;
}
posted @ 2012-11-10 15:32  To be an ACMan  Views(328)  Comments(0)    收藏  举报