HDU 1059 多重背包问题

问题大意:

有价值1-6的六种物品,分别规定其数目,问是否存在一种方法能使这些物品不拆分就能平均分给两个人

 

 1 #include <cstdio>

 2 #include <cstring>

 3 #include <iostream>

 4 using namespace std;

 5 

 6 int v[7] , ans , k;

 7 int dp[500000];

 8 //0-1背包

 9 void zeroPack(int w , int v)

10 {

11     for(int i = ans ; i>=w ; i--)

12         dp[i] = max(dp[i] , dp[i - w]+v);

13 }

14 //完全背包

15 void compPack(int w , int v)

16 {

17     for(int i = w ; i<=ans ; i++)

18         dp[i] = max(dp[i] , dp[i - w]+v);

19 }

20 //多重背包

21 void multiPack(int n , int w , int v)

22 {

23     if(n*v > ans) compPack(w , v);

24     else{

25         int t = 1;

26         while(n >= t){

27             zeroPack(t*w , t*v);

28             n-=t;

29             t <<= 1;

30         }

31         if(n > 0) zeroPack(n*w , n*v);

32     }

33 }

34 

35 int main()

36 {

37     int cas = 0;

38     while(1){

39         ans = 0;

40         k = 0;

41         for(int i = 0 ; i<6 ; i++){

42             scanf("%d" , v+i);

43             ans += v[i]*(i+1);

44         }

45         if(ans == 0) break;

46 

47         if(ans & 1){

48             printf("Collection #%d:\n" , ++cas);

49             puts("Can't be divided.");

50             puts("");

51             continue;

52         }

53         ans >>= 1;

54         memset(dp , 0 , sizeof(dp));

55         for(int i = 0 ; i<6 ; i++){

56             multiPack(v[i] , i+1 , i+1);

57         }

58 

59         if(dp[ans] == ans){

60             printf("Collection #%d:\nCan be divided.\n\n" , ++cas);

61         }

62         else printf("Collection #%d:\nCan't be divided.\n\n" , ++cas);

63     }

64     return 0;

65 }

 

你可能感兴趣的:(HDU)