首页 > 代码库 > POJ 2392 Space Elevator
POJ 2392 Space Elevator
多重背包问题。
我的背包训练第三题,多重背包。似乎有点理解多重背包了。
我对背包九讲多重背包的理解:
当某件物品 体积*数量 超过背包的容积的时候,这就做完全背包(相当于无限取)
void completepack(int h,int cost,int a) { for(int i=cost;i<=a;i++) dp[i]=max(dp[i],dp[i-cost]+h); }
而某件物品有多件却不能装满背包的时候,一件一件的来做01背包 太浪费。然后采取二进制的办法,每次乘2;
把每次乘2 的 来做一次01 背包。这样时间复杂度降低 。
void zeroonepack(int h,int cost,int a) { for(int i=a;i>=cost;i--) dp[i]=max(dp[i],dp[i-cost]+h); }
这样分开然后再分解,让多重背包就简单起来了。
void multiplepack(int h,int cost,int c,int a) { if(cost*c>=a) { completepack(h,cost,a); return; //相当于做一次完全背包 } int k=1; while(k<c) { zeroonepack(h*k,cost*k,a); c-=k; k*=2; //多次01背包 } zeroonepack(h*c,cost*c,a); }
AC 代码:
#include<cstdio> #include<cstring> #include<string> #include<queue> #include<algorithm> #include<queue> #include<map> #include<stack> #include<iostream> #include<list> #include<set> #include<cmath> #define INF 0x7fffffff #define eps 1e-6 #define LL long long using namespace std; int dp[40001]; int n; struct lx { int h,c,a; }l[401]; bool cmp(lx a,lx b) { return a.a<b.a; } void zeroonepack(int h,int cost,int a) { for(int i=a;i>=cost;i--) dp[i]=max(dp[i],dp[i-cost]+h); } void completepack(int h,int cost,int a) { for(int i=cost;i<=a;i++) dp[i]=max(dp[i],dp[i-cost]+h); } void multiplepack(int h,int cost,int c,int a) { if(cost*c>=a) { completepack(h,cost,a); return; } int k=1; while(k<c) { zeroonepack(h*k,cost*k,a); c-=k; k*=2; } zeroonepack(h*c,cost*c,a); } int main() { while(scanf("%d",&n)!=EOF) { int m=0; for(int i=0;i<n;i++) { scanf("%d%d%d",&l[i].h,&l[i].a,&l[i].c); m=max(m,l[i].a); } memset(dp,0,sizeof(dp)); sort(l,l+n,cmp); for(int i=0;i<n;i++) { multiplepack(l[i].h,l[i].h,l[i].c,l[i].a); } int ans=0; for(int i=0;i<=m;i++) //printf("%d =\n",dp[i]); ans=max(ans,dp[i]); printf("%d\n",ans); } }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。