POJ 2392 Space Elevator(贪心+多重背包)
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(多重背包)
显然塔的总高度不会超过最大的a[i],而a[i]之前的可以到达的高度 是由a值更小的块组成,所以按照a从小到大的顺序去转移. 然后就是多重背包判断存在性了,几乎和coin那题一样. 数据没coin丧病 ...
- POJ 2392 Space Elevator 贪心+dp
题目链接: http://poj.org/problem?id=2392 题意: 给你k类方块,每类方块ci个,每类方块的高度为hi,现在要报所有的方块叠在一起,每类方块的任何一个部分都不能出现在ai ...
- POJ 2392 Space Elevator(多重背包变形)
Q: 额外添加了最大高度限制, 需要根据 alt 对数据进行预处理么? A: 是的, 需要根据 alt 对数组排序 Description The cows are going to space! T ...
- poj 2392 Space Elevator(多重背包+先排序)
Description The cows are going to space! They plan to achieve orbit by building a sort of space elev ...
- POJ 2392 Space Elevator 背包题解
多重背包.本题不须要二分优化.相对简单点.由于反复数十分小,小于10. 而添加一个限制每种材料的高度做法.假设使用逆向填表,那么仅仅须要从这个高度往小递归填表就能够了. 还有就是注意要排序,以限制高度 ...
- poj[2392]space elevator
Description The cows are going to space! They plan to achieve orbit by building a sort of space elev ...
- POJ 2392 Space Elevator DP
该题与POJ 1742的思路基本一致:http://www.cnblogs.com/sevenun/p/5442279.html(多重背包) 题意:给你n个电梯,第i个电梯高h[i],数量有c[i]个 ...
- poj 2392 建塔(多重背包+不定上界)
http://blog.csdn.net/libin56842/article/details/9492351 这次比较理解那个!dp[j]是为了什么,因为是滚动数组,没有这个的话used那边会出问题 ...
- POJ 3260 The Fewest Coins(多重背包+全然背包)
POJ 3260 The Fewest Coins(多重背包+全然背包) http://poj.org/problem?id=3260 题意: John要去买价值为m的商品. 如今的货币系统有n种货币 ...
随机推荐
- hdu 1534(差分约束)
Schedule Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- eclispe启动进入子项目的解决
问题描述: In Package Explorer I right-clicked on project and selected "Open in New Window". Ne ...
- 使用Derby ij客户端工具
Derby是开源的.嵌入式的Java数据库程序,ij是Derby提供的客户端工具,相当于其他数据库提供的sqlplus工具. ij是纯Java的程序,不用安装,使用起来就像运行普通的Java应用程序一 ...
- mysql数据库设计之物理设计
一.存储引擎 推荐使用Innodb,这也是mysql默认使用的存储引擎,支持事务 二.属性的选择 字符选择: 1.char,存定长,速度快,存在空间浪费的可能,会处理尾部空格,上限255字节.(utf ...
- AC日记——pigs poj 1149
POJ - 1149 思路: 最大流: 代码: #include <cstdio> #include <cstring> #include <iostream> # ...
- Redis 源码走读(一)事件驱动机制与命令处理
eventloop 从 server.c 的 main 方法看起 int main(int argc, char **argv) { ....... aeSetBeforeSleepProc(serv ...
- json数据格式了解
json数据格式介绍: https://en.wikipedia.org/wiki/JSON JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式 json语法 ...
- python3类方法,实例方法和静态方法
今天简单总结下python的类方法,实例方法,静态方法. python默认都是实例方法,也就是说,只能实例对象才能调用这个方法. 那是不是说类方法也只能被类对象本身来调用呢,当然,不是.类方法既可以被 ...
- 【点分治】bzoj1316 树上的询问
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; #defin ...
- 【权值分块】bzoj3224 Tyvj 1728 普通平衡树
权值分块和权值线段树的思想一致,离散化之后可以代替平衡树的部分功能. 部分操作的时间复杂度: 插入 删除 全局排名 全局K大 前驱 后继 全局最值 按值域删除元素 O(1) O(1) O(sqrt(n ...