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 }

你可能感兴趣的:(div)