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种货币 ...
随机推荐
- docker从零开始网络(五)null网络
禁用容器的网络连接 预计阅读时间: 1分钟 如果要完全禁用容器上的网络堆栈,可以--network none在启动容器时使用该标志.在容器内,仅创建环回设备.以下示例说明了这一点. 1.创建容器. [ ...
- runtimeService.startProcessInstanceById("process:6:55036", 2222, variables) SQL语句
JAVA: variables:{ user_flow_start_dept : "3333"} runtimeService.startProcessInstanceById(& ...
- 360开源的pika
http://www.360doc.com/content/16/0531/14/13247663_563808424.shtml https://github.com/Qihoo360/pika/b ...
- MySQL数据库中的Date,DateTime,int,TimeStamp和Time类型的对比
DATETIME 用在你需要同时包含日期和时间信息的值时.MySQL检索并且以'YYYY-MM-DD HH:MM:SS'格式显示DATETIME值,支持的范围是'1000-01-01 00:00:00 ...
- js 之面向对象
对象 是什么? 对象就是一个整体,对外提供一些操作,比如:电视机(不用知道内部的构造,只知道怎么用) 面向对象 是什么? 使用对象时,只关注对象提供的功能,不关心内部细节,比如:操作电视机(只知道用遥 ...
- C指针详解
前言:复杂类型说明 要了解指针,多多少少会出现一些比较复杂的类型,所以我先介绍一下如何完全理解一个复杂类型,要理解复杂类型其实很简单,一个类型里会出现很多运算符,他们也像普通的表达式一样,有优先级,其 ...
- 洛谷 P1316 丢瓶盖【二分答案】
题目描述 陶陶是个贪玩的孩子,他在地上丢了A个瓶盖,为了简化问题,我们可以当作这A个瓶盖丢在一条直线上,现在他想从这些瓶盖里找出B个,使得距离最近的2个距离最大,他想知道,最大可以到多少呢? 输入输出 ...
- Codeforces 180C. Letter
题目链接:http://codeforces.com/problemset/problem/180/C 题意: 给你一个仅包含大写字母和小写字母的字符串,你可以将让小写字母转化为大写字母,大写字母转化 ...
- 训练指南 UVA - 11324(双连通分量 + 缩点+ 基础DP)
layout: post title: 训练指南 UVA - 11324(双连通分量 + 缩点+ 基础DP) author: "luowentaoaa" catalog: true ...
- Oracle的锁
Oracle数据库中的锁机制 数据库是一个多用户使用的共享资源.当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况.若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数 ...