(1059)HDU

#include<iostream>
#include<cstdio>
#include<string.h>
#include<string>
#include<set>
#include<algorithm>
#include<cmath>


#define ll __int64
#define MAX 1000009
using namespace std;


int c[MAX];//件数
int w[MAX];//尺寸
int v[MAX];//价值
int dp[MAX];


int Count;//分解完的物品总数
int Value[MAX];//分解完的每件物品的价值
int Size[MAX];//分解完每件物品的体积
int V;//总价值
int d;


int main()
{
    d = 1;
    while(~scanf("%d%d%d%d%d%d",&c[1],&c[2],&c[3],&c[4],&c[5],&c[6]))
    {
        if(c[1]+c[2]+c[3]+c[4]+c[5]+c[6]==0)break;
        V = 0;
        for(int i = 1; i<=6; i++)
        {
            v[i] = i;
            V+=c[i]*i;
        }
        //二进制处理
        Count = 1;
        for(int i = 1; i<=6; i++)
        {
            for(int j = 1; j<=c[i]; j<<=1)
            {
                Value[Count++] = j*v[i];
                c[i]-=j;
            }
            if(c[i]>0)
            {
                Value[Count++] = c[i]*v[i];
            }
        }


        int VV = V/2;
        //转化01背包
        memset(dp,0,sizeof(dp));
        for(int i = 1; i<Count; i++)
        {
            for(int j = VV; j>=Value[i]; j--)
            {
                dp[j] = max(dp[j],dp[j-Value[i]]+Value[i]);
            }
        }
        printf("Collection #%d:\n",d++);
        if(dp[VV] == V - VV)
            printf("Can be divided.\n\n");
        else
            printf("Can't be divided.\n\n");
    }
    return 0;

}

分数,问你分的价值能否一样,这里不涉及物体所占的体积,所以w[i]是不用算的,我们直接算的是价值,所以在01背包部分我们写的是

dp[j] = max(dp[j],dp[j-Value[i]]+Value[i]);

注意这里就可以,还有就是对多重背包的二进制分解,这里贴个博客,对二进制有很好的解释

//http://blog.csdn.net/lyhvoyage/article/details/8545852
我觉得上面说的我明白····

你可能感兴趣的:((1059)HDU)