poj 2392 多重背包

题意:有几个砖,给出高度,能放的最大高度和数目,求这些砖能垒成的最大高度

依据lim排个序,按一层一层进行背包

 1 #include<cstdio>

 2 #include<iostream>

 3 #include<algorithm>

 4 #include<cstring>

 5 #include<cmath>

 6 #include<queue>

 7 using namespace std;

 8 const int maxn=40005;

 9 int n,m,t;

10 int dp[maxn];

11 struct Node

12 {

13     int h,c;

14     int l;

15     void input()

16     {

17         scanf("%d%d%d",&h,&l,&c);

18     }

19 }node[maxn];

20 bool cmp(Node a,Node b)

21 {

22     return a.l<b.l;

23 }

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

25 void ZeroOnePack(int cost,int weight,int lim)

26 {

27     for(int i=lim;i>=cost;i--)

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

29 }

30 

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

32 void CompletePack(int cost,int weight,int lim)

33 {

34     for(int i=cost;i<=lim;i++)

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

36 }

37 

38 //多重背包

39 void MultiplePack(int cost,int weight,int amount,int lim)

40 {

41     if(cost*amount>=lim) CompletePack(cost,weight,lim);

42     else

43     {

44         int k=1;

45         while(k<amount)

46         {

47             ZeroOnePack(k*cost,k*weight,lim);

48             amount-=k;

49             k<<=1;

50         }

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

52     }

53 }

54 int main()

55 {

56     int i,j,k;

57     #ifndef ONLINE_JUDGE

58     freopen("1.in","r",stdin);

59     #endif

60     while(scanf("%d",&n)!=EOF)

61     {

62         for(i=0;i<n;i++)    node[i].input();

63         sort(node,node+n,cmp);

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

65         for(i=0;i<n;i++)

66         {

67             MultiplePack(node[i].h,node[i].h,node[i].c,node[i].l);

68         }

69         int maxh=node[n-1].l;

70         int ans=0;

71         for(i=0;i<=maxh;i++)

72         {

73             ans=max(dp[i],ans);

74         }

75         printf("%d",ans);

76     }

77     return 0;

78 }

 

你可能感兴趣的:(poj)