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 和 所有梯子高度之和 的较小值

转载于:https://www.cnblogs.com/xinsheng/p/3463863.html

POJ 2392 Space Elevator(多重背包变形)相关推荐

  1. poj 2392 Space Elevator

    题意 :给定n种积木,每种积木都有一个高度hi,一个数量ci,还有一个限制条件,这个积木所在的位置不能高于ai,问能叠起的最大高度// 这里有个问题需要注意 就是ai小的要先进行背包 不然 在 ai高 ...

  2. POJ 1014 Dividing(多重背包 + 倍增优化)

    题意: 求一种划分方案使结果最公平. 思路: 多重背包,然后把物品分为 2^0, 2^1, ... , 2^k,... 等. #include <iostream> #include &l ...

  3. POJ-1384 Piggy-Bank 多重背包变形

    题意 给我们一个容器的容量m n个物品 每个物品有不同的花费和价值 问我们再每个物品无限个的情况下 最后正好装满最后得到的最小价值是多少 如果装不满 就输出impossible 分析 目标状态:最小价 ...

  4. POJ 1014 Dividing【多重背包+二进制优化】

    大意: 价值1, 2, 3, --, 6的物品分别a1, a2, --, a5, a6件 问能否把这些物品分成两份,使其具有相同的价值(所有物品必须全部用上) 分析: 给个物品有多件,即多重背包 只要 ...

  5. poj 2063 Investment(01背包变形)

    http://poj.org/gotoproblem?pid=2063 (1)上限 m 一直上升的 n 次01背包问题,比一般的01背包多了一重循环: (2)本题出现了各种错误:1)刚开始,没注意 m ...

  6. poj 1252 Euro Efficiency (01背包变形)

    http://poj.org/gotoproblem?pid=1252 (1)不是单纯的01背包问题,硬币有去有回(即有正有负),这使得用想买你的解法,上限难以确定,所以我开了dp[10000]的数组 ...

  7. 【POJ - 2392】Space Elevator (dp,优秀的背包问题)

    题干: The cows are going to space! They plan to achieve orbit by building a sort of space elevator: a ...

  8. poj 2392 dp 不是很懂哎!!!Space Elevator

    大意:有K种block去建塔,每种每个都有一个高度H,用了当前的block塔的高度不能超出a,和每种的数量.求塔最高能建多高. 分析:这题就是一个多重背包,但有一点变动,必须先以a从小到大排序,因为如 ...

  9. POJ - 2392 朴素多重背包 + 贪心 WA与AC代码细节分析

    我们先来看下普通的朴素多重背包(拆成01背包求解) n种物品,背包大小w,每种物品重量 wi,价值 vi,个数 ci dp[j] 表示 大小为 j 的背包含有的最大价值,即 物品重量和 小于等于 j ...

最新文章

  1. Centos配置yum为阿里源
  2. 1.在Linux下如何使用软盘、光盘以及DOS等非Linux分区
  3. Mysql是否开启binlog日志开启方法
  4. Linux驱动学习笔记之并发控制
  5. 洛谷 P2184 贪婪大陆 解题报告
  6. php 内置mail 包,配置php自带的mail功能
  7. 使用 CodeIgniter 框架快速开发 PHP 应用(一)
  8. 想学python买什么书好-学python3什么书好
  9. Q106:Linux系统下安装编译PBRT-V3
  10. 添加购物车功能全部代码
  11. 黑马程序员Java零基础视频教程(2022最新Java)B站视频学习笔记-Day1-Java入门
  12. 容大热敏打印机打印纸张出半截,测试页不出嗡嗡响
  13. 【idea使用】主题文字修改
  14. 局域网传文件_跨平台传输文件方案大汇总(中篇)——可能全网最全的传输方案了...
  15. 推荐电影 梦工厂经典电影列表 1996-2012
  16. 塔望食业洞察|人参饮料行业环境 市场现状及发展思考
  17. 紫光云服务器芯片,紫光云与新华三半导体共建芯片设计云2.0 携手打造一站式云端芯片平台...
  18. 读javascript高级程序设计02-变量作用域
  19. 恶意软件分析实战02-分析3个恶意程序
  20. 如何在网页中调用百度地图API

热门文章

  1. 计算机应用技术和信息化,浅析企业计算机应用技术和信息化建设
  2. sql not exists用法_牛客网数据库SQL实战详细剖析(5160)(更新完结)
  3. 深度学习TensorFlow的55个经典案例
  4. 集合的交并差 -python
  5. hdu 1358 Period
  6. android书籍和教程推荐--不断更新
  7. dubbo常见的一些面试题
  8. linux环境知识点备忘录
  9. 用OpenCV实现Otsu算法
  10. (六)WebRTC手记之WebRtcVideoEngine2模块