Dividing 多重背包 倍增DP

                    Dividing

 

给出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 }

 

posted @ 2015-04-10 18:17  daydaycode  阅读(129)  评论(0编辑  收藏  举报