您的位置:首页 > 其它

POJ 2392 Space Elevator 贪心+dp

2016-05-05 13:13 183 查看

题目链接:

http://poj.org/problem?id=2392

题意:

给你k类方块,每类方块ci个,每类方块的高度为hi,现在要报所有的方块叠在一起,每类方块的任何一个部分都不能出现在ai以上的高度,问这些方块能叠的最高高度。

题解:

首先按ai升序排序,尽量让高度限制低的先排掉,如果不这样做一些转移会失效掉:

比如:h1=3,a1=3;h2=4,a2=7

如果先搭1再搭2则合法,但反过来则变成无效的转移了。

处理好顺序之后跑一遍背包就可以了,因为最大高度为40000,比较小,所以用判定的方式跑一遍就可以了。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

const int maxn = 40000 + 40;
const int maxm = 444;

int k;
int dp[maxn],used[maxn];
int hi[maxm], ai[maxm], ci[maxm];

int ran[maxm];
bool cmp(int x,int y) {
return ai[x] < ai[y];
}

void init() {
memset(dp, 0, sizeof(dp));
for (int i = 0; i < k; i++) ran[i] = i;
}

int main() {
while (scanf("%d", &k) == 1 && k) {
init();
for (int i = 0; i < k; i++) {
scanf("%d%d%d", hi + i, ai + i, ci + i);
}
sort(ran, ran + k,cmp);
dp[0] = 1;
for (int i = 0; i < k; i++) {
int t = ran[i];
memset(used, 0, sizeof(used));
for (int h = hi[t]; h <= ai[t]; h++) {
//dp[h]==0一定也要记得写,这里也是个贪心
if (dp[h]==0&&dp[h - hi[t]] && used[h - hi[t]] + 1 <= ci[t]) {
dp[h] = 1; used[h] = used[h - hi[t]] + 1;
}
}
}
int ans = 0;
for (int i = 40000; i >= 0; i--) if (dp[i]) {
ans = i; break;
}
printf("%d\n", ans);
}
return 0;
}


总结:

这题和经典的多重背包问题还是有些差别的:

这题是求给定一系列元素的高度,个数,高度限制,求最大高度。

而经典多重背包问题是给定一系列元素的价值,体积,体积限制,求最大价值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: