Dividing 多重背包 倍增DP
给出n个物品的价值和数量,问是否能够平分。
1 #include <iostream> 2 #include <cstring> 3 #include <cmath> 4 #include <cstdio> 5 #include <algorithm> 6 #include <vector> 7 #include <string> 8 #include <map> 9 #include <set> 10 #include <stack> 11 #include <queue> 12 #include <sstream> 13 #include <iomanip> 14 using namespace std; 15 typedef long long LL; 16 const int INF=0x4fffffff; 17 const double EXP=1e-5; 18 const int MS=100005; 19 const int SIZE=1000005; 20 21 int cnt[MS]; 22 int kase; 23 int dp[MS]; 24 25 void solve() 26 { 27 int sum=cnt[0]*1+cnt[1]*2+cnt[2]*3+cnt[3]*4+cnt[4]*5+cnt[5]*6; 28 memset(dp,0,sizeof(dp)); 29 dp[0]=1; 30 if((sum&1)==0) 31 { 32 for(int i=0;i<6;i++) 33 { 34 int num=cnt[i]; 35 if(num==0) 36 continue; 37 for(int k=1;num>0;k<<=1) 38 { 39 int mul=min(k,num); 40 for(int j=sum/2;j>=mul*(i+1);j--) 41 dp[j]|=dp[j-mul*(i+1)]; 42 //dp[j]=max(dp[j],dp[j-mul*w[i]]+v[i]*mul); 43 num-=mul; 44 } 45 46 } 47 } 48 printf("Collection #%d:\n",kase++); 49 if((sum&1)==0&&dp[sum/2]) 50 printf("Can be divided.\n"); 51 else 52 printf("Can't be divided.\n"); 53 printf("\n"); 54 } 55 56 int main() 57 { 58 kase=1; 59 while(scanf("%d%d%d%d%d%d",&cnt[0],&cnt[1],&cnt[2],&cnt[3],&cnt[4],&cnt[5])) 60 { 61 if(cnt[0]+cnt[1]+cnt[2]+cnt[3]+cnt[4]+cnt[5]==0) 62 break; 63 solve(); 64 } 65 return 0; 66 }