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 }