题目链接: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");
}
}
}