Q: 额外添加了最大高度限制, 需要根据 alt 对数据进行预处理么?

A: 是的, 需要根据 alt 对数组排序

Description

The cows are going to space! They plan to achieve orbit by building a sort of space elevator: a giant tower of blocks. They have K (1 <= K <= 400) different types of blocks with which to build the tower. Each block of type i has height h_i (1 <= h_i <= 100) and is available in quantity c_i (1 <= c_i <= 10). Due to possible damage caused by cosmic rays, no part of a block of type i can exceed a maximum altitude a_i (1 <= a_i <= 40000).

Help the cows build the tallest space elevator possible by stacking blocks on top of each other according to the rules.

Input

* Line 1: A single integer, K

* Lines 2..K+1: Each line contains three space-separated integers: h_i, a_i, and c_i. Line i+1 describes block type i.

Output

* Line 1: A single integer H, the maximum height of a tower that can be built

Sample Input

3
7 40 3
5 23 8
2 52 6

Sample Output

48

Hint

OUTPUT DETAILS:

From the bottom: 3 blocks of type 2, below 3 of type 1, below 6 of type 3. Stacking 4 blocks of type 2 and 3 of type 1 is not legal, since the top of the last type 1 block would exceed height 40.

 

思路:

  1. 对数据预处理, 按照 alt 排序
  2. 预处理, 倍增优化, 转化成 01 背包
  3. 求解 01 背包

总结:

1. 对 3 个数组, 以其中一个为根据排序, 一种解决方法是把三个数组绑定到一个对象中, 然后对对象排序

2. 犯了个致命的错误, 48行代码写成memset(dp, 0, sizeof(int)*V); 导致当 V 比较大时, h 也被置 0 了

代码:

#include <iostream>
#include <algorithm>
using namespace std;
int K;
const int MAXN = 40010;
bool dp[40010];
int h[MAXN], a[MAXN];
int V; struct block {
int h, a, c;
bool operator<(const block &other) const {
return this->a < other.a;
}
}; block blocks[MAXN];
int pre_process() {
sort(blocks, blocks+K);
int len = 0;
for(int i = 0; i < K; i ++) {
int rem = blocks[i].c;
int j = 0;
// 预处理,
while(rem) {
if(rem >= (1<<j)) {
h[len] = (1<<j)*blocks[i].h;
a[len] = blocks[i].a;
rem -= (1<<j);
j++;
if(h[len] > a[len])
continue;
len++;
}else{
h[len] = rem*blocks[i].h;
a[len] = blocks[i].a;
len++;
rem = 0;
}
}
}
return len;
} int solve_dp() {
int len = pre_process();
// 01背包
memset(dp, 0, sizeof(dp));
dp[0] = 1;
for(int i = 0; i < len; i ++) {
for(int v = V; v >= h[i]; v--) {
if(v > a[i]) continue;
if(!dp[v] && dp[v-h[i]]) {
dp[v] = true;
//printf("dp[%d] = true\n", v);
}
}
} for(int v = V; v >= 0; v --)
if(dp[v])
return v;
}
int main() {
freopen("E:\\Copy\\ACM\\测试用例\\in.txt", "r", stdin);
cin >> K;
int h_i, a_i, c_i;
V = 0;
for(int i = 0; i < K; i ++) {
scanf("%d%d%d", &blocks[i].h, &blocks[i].a, &blocks[i].c);
V = min(V+blocks[i].h*blocks[i].c, 40000);
} cout << solve_dp() << endl;
return 0;
}

  

update: 2014年3月14日10:35:10

1. 贪心策略是最大高度较小的先放

Q1: 对物品排序会对结果产生影响吗

A1: 会的. 假设只有两个物品, 最大高度不同, 显然最大高度较小的放前面可以获摆放的更高

Q2: 第二层循环, V 是怎么初始化的

A2: 上面的代码初始化比较随意, V 初始化为 40000 和 所有梯子高度之和 的较小值

POJ 2392 Space Elevator(多重背包变形)的更多相关文章

  1. poj 2392 Space Elevator(多重背包+先排序)

    Description The cows are going to space! They plan to achieve orbit by building a sort of space elev ...

  2. POJ 2392 Space Elevator(贪心+多重背包)

    POJ 2392 Space Elevator(贪心+多重背包) http://poj.org/problem?id=2392 题意: 题意:给定n种积木.每种积木都有一个高度h[i],一个数量num ...

  3. POJ 2392 Space Elevator(多重背包)

    显然塔的总高度不会超过最大的a[i],而a[i]之前的可以到达的高度 是由a值更小的块组成,所以按照a从小到大的顺序去转移. 然后就是多重背包判断存在性了,几乎和coin那题一样. 数据没coin丧病 ...

  4. POJ 2392 Space Elevator 背包题解

    多重背包.本题不须要二分优化.相对简单点.由于反复数十分小,小于10. 而添加一个限制每种材料的高度做法.假设使用逆向填表,那么仅仅须要从这个高度往小递归填表就能够了. 还有就是注意要排序,以限制高度 ...

  5. poj[2392]space elevator

    Description The cows are going to space! They plan to achieve orbit by building a sort of space elev ...

  6. poj2392 Space Elevator(多重背包)

    http://poj.org/problem?id=2392 题意: 有一群牛要上太空.他们计划建一个太空梯-----用一些石头垒.他们有K种不同类型的石头,每一种石头的高度为h_i,数量为c_i,并 ...

  7. POJ 2392 Space Elevator DP

    该题与POJ 1742的思路基本一致:http://www.cnblogs.com/sevenun/p/5442279.html(多重背包) 题意:给你n个电梯,第i个电梯高h[i],数量有c[i]个 ...

  8. POJ 2392 Space Elevator 贪心+dp

    题目链接: http://poj.org/problem?id=2392 题意: 给你k类方块,每类方块ci个,每类方块的高度为hi,现在要报所有的方块叠在一起,每类方块的任何一个部分都不能出现在ai ...

  9. poj 1742 Coins (多重背包)

    http://poj.org/problem?id=1742 n个硬币,面值分别是A1...An,对应的数量分别是C1....Cn.用这些硬币组合起来能得到多少种面值不超过m的方案. 多重背包,不过这 ...

随机推荐

  1. Servlet/Filter发布后与其他页面的相对路径

    1.Servlet 3个文件 E:\web.workspace\mldndemo\WebContent\ch14\regist.html E:\web.workspace\mldndemo\WebCo ...

  2. jquery 时间戳和日期时间转化

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...

  3. ADO中记录集recordSet的使用

    _RecordsetPtr使用方法 _variant_t vUsername,vID,vname; //变量声明_RecordsetPtr m_pRecordset;     //记录集CString ...

  4. c#写一个网站后台扫描器

    主要分成了那么几个步骤: 1.HTTP状态码 2.字典的导入 3.显示在listview控件当中 第一步: 先来实现HTTP状态码200的判断 try { req = (HttpWebRequest) ...

  5. hive 进阶笔记

    -- mysql方式 create table account_channel(account_ String,channel_ String) as select a.account,b.chann ...

  6. 【WPF】两个下拉列表ComboBox的级联

    需求:两个ComboBox的级联,实现城市–小区级联. 问题:个人感觉WPF的核心应该是数据绑定这块.由于时间紧迫,粗略看Binding也是一头雾水,所以用了比较简单的方法做了两个下拉列表级联的效果: ...

  7. SpringMVC @ModelAttribute 详解

    [@Controller]4 详解@ModelAttribute http://blog.sina.com.cn/s/blog_6d3c1ec601017q4p.html A.@ModelAttrib ...

  8. eclipse安装使用教程

    eclipse安装使用教程 很多人都知道要用eclipse来做java开发,但很多的新手朋友却不知道怎么下载和安装eclipse. 下面给你介绍一下怎么下载和安装eclipse来用于自己的学习或者项目 ...

  9. hdu6199 gems gems gems dp+博弈

    /** 2017 ACM/ICPC Asia Regional Shenyang Online 解题报告 题目:hdu6199 gems gems gems 链接:http://acm.hdu.edu ...

  10. centsos7修改主机名 [root@st152 ~]# cat /etc/hostname

    CentOS7修改服务器主机名方法CentOS7下修改主机名第一种:hostname 主机名01.hostname 主机名称 <pre name="code" class=& ...