hdoj1059 Dividing(多重背包+二进制化简)

来源:互联网 发布:淘宝罗技那家店是正品 编辑:程序博客网 时间:2024/06/05 16:18

关于背包问题的解答链接http://www.cppblog.com/tanky-woo/archive/2010/07/31/121803.html

首先计算出总的价值数sum,如果sum为奇数,则一定无法对半分配

如果sum为偶数,可直接看作多重背包问题:载重为sum/2的背包是否可以被恰好装满。

#include<stdio.h>#include<string>#define max2147483647#define min(-max-1)using namespace std;int dp[400000];int main(){int a[7],b[7];int c[125];int i,j,sum,t=1;while(~scanf("%d%d%d%d%d%d",&a[1],&a[2],&a[3],&a[4],&a[5],&a[6])){int k=1;        if(a[1]==0&&a[2]==0&&a[3]==0&&a[4]==0&&a[5]==0&&a[6]==0)break;        sum=0;        for(i=1;i<=6;i++)        {        int temp=1;        sum+=i*a[i];        while(a[i]>temp)        {        c[k++]=i*temp;        a[i]-=temp;        temp=temp*2;        }        c[k++]=i*a[i];        }        if(sum%2==1){printf("Collection #%d:\nCan't be divided.\n\n",t++);continue;}sum=sum/2;for(i=1;i<=sum;i++)dp[i]=min;for(i=1;i<k;i++)for(j=sum;j>=c[i];j--){if(dp[j]<dp[j-c[i]]+c[i])dp[j]=dp[j-c[i]]+c[i];}if(dp[sum]>0)printf("Collection #%d:\nCan be divided.\n\n",t++);else printf("Collection #%d:\nCan't be divided.\n\n",t++);}return 0;} 



原创粉丝点击