hdoj1059 Dividing 多重背包

来源:互联网 发布:java怎么制作游戏 编辑:程序博客网 时间:2024/06/05 00:38

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1059

题意:第i类物品有a[i]件,问能否将其平分。

分析:二进制优化,然后用01背包做。

code:

#include<cstdio>
#define max(a,b) (a>b?a:b)
const int MAXN=20000;
const int INF=99999999;
int value[MAXN],dp[MAXN*6/2];
int a[7],cnt;
void change(int c,int v){
    for(int k=1;k<=c;k<<=1){
        value[cnt++]=k*v;
        c-=k;
    }
    if(c>0){
        value[cnt++]=c*v;
    }
}//二进制优化
int main(void){
    int CASE=0;
    while(scanf("%d%d%d%d%d%d",&a[1],&a[2],&a[3],&a[4],&a[5],&a[6])&&(a[1]+a[2]+a[3]+a[4]+a[5]+a[6])){
        int sum=0;
        for(int i=1;i<=6;++i)
            sum+=a[i]*i;
        printf("Collection #%d:\n",++CASE);
        if(sum&1){
            printf("Can't be divided.\n\n");
        }//如果sum是奇数直接打印
        else{
            cnt=0;
            for(int i=1;i<=6;++i)
                change(a[i],i);
            for(int i=1;i<=sum/2;++i)
                dp[i]=-INF;
            dp[0]=0;
            for(int i=0;i<cnt;++i)
            for(int j=sum/2;j>=value[i];j--){
                dp[j]=max(dp[j],dp[j-value[i]]+value[i]);
            }
            printf(dp[sum/2]==sum/2?"Can't be divided.\n\n":"Can be divided.\n\n");
        }
    }
}


0 0
原创粉丝点击