hdu 1059 多重背包

题意:价值分别为1,2,3,4,5,6的物品个数分别为a[1],a[2],a[3],a[4],a[5],a[6],问能不能分成两堆价值相等的。
解法:转化成多重背包
 1 #include<stdio.h>

 2 #include<string.h>

 3 #include<algorithm>

 4 #include<iostream>

 5 using namespace std;

 6 

 7 int dp[120010];

 8 int a[10];

 9 

10 int nValue;

11 

12 //0-1背包,代价为cost,获得的价值为weight

13 void ZeroOnePack(int cost,int weight)

14 {

15     for(int i=nValue;i>=cost;i--)

16       dp[i]=max(dp[i],dp[i-cost]+weight);

17 }

18 

19 //完全背包,代价为cost,获得的价值为weight

20 void CompletePack(int cost,int weight)

21 {

22     for(int i=cost;i<=nValue;i++)

23       dp[i]=max(dp[i],dp[i-cost]+weight);

24 }

25 

26 //多重背包

27 void MultiplePack(int cost,int weight,int amount)

28 {

29     if(cost*amount>=nValue) CompletePack(cost,weight);

30     else

31     {

32         int k=1;

33         while(k<amount)

34         {

35             ZeroOnePack(k*cost,k*weight);

36             amount-=k;

37             k<<=1;

38         }

39         ZeroOnePack(amount*cost,amount*weight);//这个不要忘记了,经常掉了

40     }

41 }

42 

43 int main()

44 {

45     int iCase=0;

46     while(1)

47     {

48         iCase++;

49         int tol=0;

50         for(int i=1;i<=6;i++)

51         {

52             scanf("%d",&a[i]);

53             tol+=i*a[i];

54         }

55         if(tol==0)break;

56         printf("Collection #%d:\n",iCase);

57         if(tol%2!=0)

58         {

59             printf("Can't be divided.\n\n");

60             continue;

61         }

62         else

63         {

64             nValue=tol/2;

65 

66         }

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

68         for(int i=1;i<=6;i++)

69           MultiplePack(i,i,a[i]);

70         if(dp[nValue]==nValue)printf("Can be divided.\n\n");

71         else printf("Can't be divided.\n\n");

72     }

73     return 0;

74 }

 

你可能感兴趣的:(HDU)