hdu 1059 多重背包

题意:价值分别为1,2,3,4,5,6的物品个数分别为a[1],a[2],a[3],a[4],a[5],a[6],问能不能分成两堆价值相等的。
解法:转化成多重背包
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 #include<iostream>
 5 using namespace std;
 6 
 7 int dp[120010];
 8 int a[10];
 9 
10 int nValue;
11 
12 //0-1背包,代价为cost,获得的价值为weight
13 void ZeroOnePack(int cost,int weight)
14 {
15     for(int i=nValue;i>=cost;i--)
16       dp[i]=max(dp[i],dp[i-cost]+weight);
17 }
18 
19 //完全背包,代价为cost,获得的价值为weight
20 void CompletePack(int cost,int weight)
21 {
22     for(int i=cost;i<=nValue;i++)
23       dp[i]=max(dp[i],dp[i-cost]+weight);
24 }
25 
26 //多重背包
27 void MultiplePack(int cost,int weight,int amount)
28 {
29     if(cost*amount>=nValue) CompletePack(cost,weight);
30     else
31     {
32         int k=1;
33         while(k<amount)
34         {
35             ZeroOnePack(k*cost,k*weight);
36             amount-=k;
37             k<<=1;
38         }
39         ZeroOnePack(amount*cost,amount*weight);//这个不要忘记了,经常掉了
40     }
41 }
42 
43 int main()
44 {
45     int iCase=0;
46     while(1)
47     {
48         iCase++;
49         int tol=0;
50         for(int i=1;i<=6;i++)
51         {
52             scanf("%d",&a[i]);
53             tol+=i*a[i];
54         }
55         if(tol==0)break;
56         printf("Collection #%d:\n",iCase);
57         if(tol%2!=0)
58         {
59             printf("Can't be divided.\n\n");
60             continue;
61         }
62         else
63         {
64             nValue=tol/2;
65 
66         }
67         memset(dp,0,sizeof(dp));
68         for(int i=1;i<=6;i++)
69           MultiplePack(i,i,a[i]);
70         if(dp[nValue]==nValue)printf("Can be divided.\n\n");
71         else printf("Can't be divided.\n\n");
72     }
73     return 0;
74 }

 

posted @ 2015-03-21 21:19  miao_a_miao  阅读(149)  评论(0编辑  收藏  举报