多重背包
题意:价值为1,2,3,4,5,6. 分别有n[1],n[2],n[3],n[4],n[5],n[6]个。
求能否找到满足价值刚好是所有的一半的方案。
View Code
1 /* 2 多重背包 3 */ 4 #include<stdio.h> 5 #include<stdlib.h> 6 #include<string.h> 7 #include<iostream> 8 #include<algorithm> 9 #include<queue> 10 #include<map> 11 #include<math.h> 12 using namespace std; 13 const int maxn = 10; 14 int n[ maxn ]; 15 int sumv,V; 16 int dp[ 60011 ]; 17 void bag01( int cost,int weight ){ 18 for( int i=V;i>=cost;i-- ){ 19 dp[ i ]=max(dp[ i ],dp[ i-cost ]+weight); 20 } 21 return ; 22 } 23 void bagall( int cost ,int weight ){ 24 for( int i=cost;i<=V;i++ ){ 25 dp[ i ]=max( dp[ i ],dp[ i-cost ]+weight); 26 } 27 return ; 28 } 29 30 void mul_bag( int cost,int weight,int num ){ 31 if( cost*num>=V ){ 32 bagall( cost,weight ); 33 return ; 34 } 35 int k=1; 36 while( k<=num ){ 37 bag01( k*cost,k*weight ); 38 num-=k; 39 k*=2; 40 } 41 bag01( num*cost,num*weight ); 42 return ; 43 } 44 int main() 45 { 46 int i,k=1; 47 while(cin>>n[0]>>n[1]>>n[2]>>n[3]>>n[4]>>n[5],n[0]+n[1]+n[2]+n[3]+n[4]+n[5]) 48 { 49 memset(dp,0,sizeof(dp)); 50 sumv=n[0]+n[1]*2+n[2]*3+n[3]*4+n[4]*5+n[5]*6; 51 if(sumv%2==1) 52 { 53 printf("Collection #%d:\nCan't be divided.\n\n",k++); 54 continue; 55 } 56 V=sumv/2; 57 for(i=0;i<6;i++) 58 { 59 if(n[i]) mul_bag(i+1,i+1,n[i]); 60 } 61 if(V==dp[V]) printf("Collection #%d:\nCan be divided.\n\n",k++); 62 else printf("Collection #%d:\nCan't be divided.\n\n",k++); 63 } 64 return 0; 65 }