http://acm.hdu.edu.cn/showproblem.php?pid=1059
重做。。
发现用背包判断是否能装一半的价值。
判断是否存满就行。。。
注意直接 01 背包会超时。
所以用二进制优化对多重背包进行优化。
当大于条件时,可以用完全背包
wa的原因就是。。没有判断奇数时不可以的。。
还有就是忘记加 case。。
重做。。
发现用背包判断是否能装一半的价值。
判断是否存满就行。。。
注意直接 01 背包会超时。
所以用二进制优化对多重背包进行优化。
当大于条件时,可以用完全背包
wa的原因就是。。没有判断奇数时不可以的。。
还有就是忘记加 case。。
注意范围;单个不超过2e4 6个就要加6*2e4..
#include <bits/stdc++.h>
/* 背包,看是否存在两个数。
*/
using namespace std;
const int maxn=2e5+1000;
int a[maxn];
int v[maxn];
int dp[maxn];
int main()
{ int tt=1;
while(~scanf("%d%d%d%d%d%d",&a[0],&a[1],&a[2],&a[3],&a[4],&a[5])){
int sum=0;
for(int i=0;i<=5;i++){
if(a[i]==0)
sum++;
}
if(sum==6) return 0;
int all=0;
for(int i=0;i<=5;i++){
all+=(i+1)*(a[i]);
}
if(all%2){
printf("Collection #%d:\n",tt++);
puts("Can't be divided.");
puts("");
continue;
}
memset(dp,0,sizeof(dp));
dp[0]=1;
for(int i=0;i<=5;i++){
/*if(a[i]*(i+1)>=all/2)
{ for(int z=(i+1);z<=all/2;z++){
dp[z]=max(dp[z-(i+1)],dp[z]);
}
}*/
for(int j=1;j<=a[i];j*=2){
for(int z=all/2;z>=0;z--)
if(z>=(i+1)*j)
dp[z]=max(dp[z-(i+1)*j],dp[z]);
a[i]-=j;
}
if(a[i]){
for(int z=all/2;z>=0;z--){
if(z>=(i+1)*a[i])
dp[z]=max(dp[z-(i+1)*a[i]],dp[z]);
}
}
}
//cout<<"!!!"<<all/2<<endl;
printf("Collection #%d:\n",tt++);
if(dp[all/2])
puts("Can be divided.");
else
puts("Can't be divided.");
printf("\n");
}
return 0;
}