POJ 2392 Space Elevator(贪心+多重背包)
来源:互联网 发布:python安装视频 编辑:程序博客网 时间:2024/05/29 04:46
POJ 2392 Space Elevator(贪心+多重背包)
http://poj.org/problem?id=2392
题意:
题意:给定n种积木,每种积木都有一个高度h[i],一个数量num[i],还有一个限制条件,这个积木所在的位置不能高于limit[i],问能叠起的最大高度?
分析:
本题是一道多重背包问题, 不过每个物品的选择不仅仅要受该种物品的数量num[i]限制, 且该物品还受到limit[i]的限制.
这里有一个贪心的结论:
我们每次背包选取物品时都应该优先放置当前limit[i]值最小的积木(可以画个图看看,不过不太好证明该结论). 所以我们首先把所有积木按limit[i]的值进行从小到大的排序, 然后从1编号开始选积木即可.
下面就是多重背包的过程了.
令dp[i][j]==x表示用前i个积木且总的高度<=j时能达到的最大高度为x.
初始化: dp全为0.
对于每种物品, 我们要做两种选择:
1. num[i]*high[i]>=limit[i]时, 做一次完全背包.
2. Num[i]*high[i]<limit[i]时, 需要把当前物品再分类, 然后做多次01背包即可.
最终所求: dp[n][j]的最大值. 其中j遍历[0,limit[n]]内所有数.
注意: 本来按道理dp[i][j]的语义是<=j时, 而不是正好等于j时. 我们直接输出dp[n][limit[n]]即可的. 但是本题有点特殊. 看下面这组数据:
2
5 11 3
8 12 2
对应的最终dp输出为:
i=0 dp[i]=0
i=1 dp[i]=0
i=2 dp[i]=0
i=3 dp[i]=0
i=4 dp[i]=0
i=5 dp[i]=5
i=6 dp[i]=5
i=7 dp[i]=5
i=8 dp[i]=8
i=9 dp[i]=8
i=10 dp[i]=10
i=11 dp[i]=10
i=12 dp[i]=8
为什么会得到上面奇怪的数据呢? 因为当选择第1个物品(high[1]==5)时, 进行的背包过程只做到了11高度就停了, 没有继续到所有数据. 所以最终需要遍历所有dp数据.
AC代码:
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=40000+5;int n;//木块种类struct Node//每种木块{ int high,num,limit; bool operator<(const Node &rhs)const { return limit<rhs.limit; }}nodes[400+5];int dp[maxn];//一次01背包过程void ZERO_ONE_PACK(int cost,int limit){ for(int i=limit;i>=cost;i--) dp[i] = max(dp[i], dp[i-cost]+cost);}//一次完全背包过程void COMPLETE_PACK(int cost,int limit){ for(int i=cost;i<=limit;i++) dp[i] = max(dp[i], dp[i-cost]+cost);}//一次多重背包过程void MULTIPLY_PACK(int cost,int limit,int num){ if(cost*num>=limit) { COMPLETE_PACK(cost,limit); return ; } int k=1; while(k<num) { ZERO_ONE_PACK(cost*k,limit); num-=k; k*=2; } ZERO_ONE_PACK(cost*num,limit);}int main(){ while(scanf("%d",&n)==1) { //读取输入+排序 for(int i=1;i<=n;i++) scanf("%d%d%d",&nodes[i].high,&nodes[i].limit,&nodes[i].num); sort(nodes+1,nodes+n+1); //初始化dp+递推 memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++) MULTIPLY_PACK(nodes[i].high, nodes[i].limit, nodes[i].num); //统计结果输出 int ans=0; for(int i=0;i<=nodes[n].limit;i++) ans=max(ans,dp[i]); printf("%d\n",ans); } return 0;}
- POJ 2392 Space Elevator(贪心+多重背包)
- poj 2392 Space Elevator 多重背包
- poj 2392 Space Elevator(多重背包变形)
- POJ 2392 Space Elevator [DP 多重背包]
- POJ 2392 Space Elevator (多重背包)
- poj 2392 Space Elevator(排序+多重背包)
- POJ 2392 Space Elevator (多重背包问题)
- POJ 2392 Space Elevator 多重背包
- POJ 2392 Space Elevator (多重背包+优化)
- poj 2392 Space Elevator (多重背包)
- poj 2392 Space Elevator(多重背包)
- POJ 2392 Space Elevator 多重背包
- poj 2392 Space Elevator (多重背包)
- POJ 2392-Space Elevator(多重背包)
- POJ 2392 Space Elevator 多重背包
- poj 2392 Space Elevator dp 多重背包
- poj Space Elevator 2392 (多重背包)
- 多重背包-POJ 2392 Space Elevator
- 生产环境下部署hadoop集群(包括dns配置,nfs共享,awk资源分发)
- 使用Corosync+Pacemaker为Icehouse L3-agent提供Active/Passive HA服务(by quqi99)
- MTK CCT之CAMERA TUNNING调试学习总结
- 《网蜂A8实战演练》——3.按键驱动
- 帕塞瓦尔定理(能量守恒定理)
- POJ 2392 Space Elevator(贪心+多重背包)
- MTK Android software Tools工具的说明
- robots.txt设置与优化
- 几条 ffmpeg 的命令
- 指针2
- Android(Lollipop/5.0) Material Design(五) 定义阴影和裁剪View
- 第二讲,我们来谈谈:“什么是二进制”
- 离散数学在计算机科学中的应用
- java.util.Date获得年、月 ,获得年需要加1900,获得月需要加1