【CH5E07】划分大理石
一道多重背包的简化版问题,把多重背包的最优性问题简化为可行性问题,计算时只需将取最优值的一步改为或运算即可。
本题有解的条件:所有物品价值的一半能被表示出来。
本人使用了最简单的二进制优化即可通过本题。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 int a[7],num,f[1000010],v[1000010],sum; 6 int main() { 7 while(1) { 8 memset(a,0,sizeof(a)); 9 sum=0; 10 for(int i=1;i<=6;i++) { 11 cin>>a[i]; 12 sum+=a[i]*i; 13 } 14 if(!sum) break ; 15 if(sum&1) { 16 puts("Can't"); 17 continue ; 18 } 19 num=0; 20 for(int i=1;i<=6;i++) { 21 int now=0; 22 for(int j=1;j*2<=a[i];j<<=1) 23 v[++num]=j*i,now+=j; 24 v[++num]=i*(a[i]-now); 25 } 26 f[0]=1; 27 for(int i=1;i<=num;i++) 28 for(int j=sum;j>=v[i];j--) 29 f[j]|=f[j-v[i]]; 30 if(f[sum>>1]) puts("Can"); 31 else puts("Can't"); 32 } 33 return 0; 34 }