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 }

 

posted @ 2015-03-22 22:33  miao_a_miao  阅读(110)  评论(0编辑  收藏  举报