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 }