链接:http://poj.org/problem?id=1014
题意: 价值为 i 的物品分别有 a[i] 个, 问是否能够均分。多重背包问题。
View Code
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 using namespace std; 7 int a[10], M, dp[100000]; 8 void zpack( int w, int v ) 9 { 10 for( int i=M; i>=w; -- i ){ 11 dp[i]=max(dp[i-w]+v, dp[i]); 12 } 13 } 14 15 void cpack( int w, int v ) 16 { 17 for( int i=w; i<=M; ++ i ){ 18 dp[i]=max(dp[i-w]+v, dp[i]); 19 } 20 } 21 22 int main( ) 23 { 24 int t=1; 25 while( scanf( "%d", &a[1] )==1 ){ 26 int s=a[1]; 27 for( int i=2; i<=6; ++ i ){ 28 scanf( "%d", &a[i] ); 29 s+=i*a[i]; 30 } 31 if( !s )break; 32 if( s&1 ){ 33 printf( "Collection #%d:\nCan't be divided.\n\n", t++ ); 34 continue; 35 } 36 M=s/2; 37 memset( dp, 0, sizeof dp ); 38 for( int i=1; i<=6;++ i ){ 39 if( i*a[i]>=M ){ 40 cpack( i, i ); 41 } 42 else{ 43 int k=1; 44 while( k<=a[i] ){ 45 zpack( k*i, k*i ); 46 a[i]-=k; 47 k<<=1; 48 } 49 zpack( i*a[i], i*a[i] ); 50 } 51 } 52 if( dp[M]==M ) printf( "Collection #%d:\nCan be divided.\n\n", t++ ); 53 else printf( "Collection #%d:\nCan't be divided.\n\n", t++ ); 54 } 55 return 0; 56 }