poj 1014 Dividing <多重背包>

链接: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 }
原文地址:https://www.cnblogs.com/jian1573/p/2634291.html