放牧代码和思想
专注自然语言处理、机器学习算法
    愛しさ 優しさ すべて投げ出してもいい

POJ 2392 Space Elevator 题解 《挑战程序设计竞赛(第2版)》

POJ 2392 Space Elevator

通天塔:奶牛们想用c_i个高h_i的积木造通天塔,每种积木不能高过a_i,求塔的最大高度。

多重背包 O(VN) 单调队列 

这题要思考的方向是往多重背包这边想,高度既是“价值”又是“重量”,背包的容积是变动的a_i。性价比恒为1,优先使用a_i小的。必须按积木的a_i从小到大的顺序递推才能覆盖全部解空间,否则a_i小的积木根本码不上去。

多重背包的O(VN)优化是利用单调队列实现,我从这里现学现卖。

《2.3 记录结果再利用的“动态规划” 需稍加思考的题目》

#ifndef ONLINE_JUDGE
#pragma warning(disable : 4996)
#endif
#include <iostream>
#include <algorithm>
#include <iterator>
using namespace std;

int f[2][40000 + 16];
pair <int, int> q[40000 + 16];			// 单调队列 first := 最优解 second:= 容积

struct Block
{
	int h, a, c;
	bool operator < (const Block & b) const
	{
		return a < b.a;
	}
};

Block block[400 + 16];

///////////////////////////SubMain//////////////////////////////////
int main(int argc, char *argv[])
{
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif
	int K;
	cin >> K;
	for (int i = 0; i < K; ++i)
	{
		cin >> block[i].h >> block[i].a >> block[i].c;
	}
	sort(block, block + K);

	int cur = 0, pre = 1;
	for (int i = 0; i < K; ++i)
	{
		swap(cur, pre);
		int v, w, m;
		v = block[i].h;
		w = block[i].h;
		m = block[i].c;
		int V = block[i].a;
					// 价值 重量 数量
		for (int mod = 0; mod < w; ++mod)
		{
			int l = 0, r = 0;		// 单调队列 首 尾
			for (int j = 0; mod + j * w <= V; ++j)
			{
				// 维持单调队列的递减特性
				while (r > l && (f[pre][mod + j * w] - j * v) > q[r - 1].first)
				{
					// 将前面小的元素都挤出去
					r--;
				}
				// 入队
				q[r++] = make_pair(f[pre][mod + j * w] - j * v, j);
				if (r - l > 0 && j - q[l].second > m)
				{
					// 队列不为空,最优解对应的缺口无法填满,出队
					l++;
				}
				f[cur][mod + j * w] = q[l].first + j * v;
			}
		}
	}

	cout << *max_element(f[cur], f[cur] + block[K - 1].a + 1) << endl;
#ifndef ONLINE_JUDGE
	fclose(stdin);
	fclose(stdout);
	system("out.txt");
#endif
	return 0;
}
///////////////////////////End Sub//////////////////////////////////
12519522 hankcs 2392 Accepted 852K 235MS C++ 1660B 2014-02-14 01:17:02

马上要开始工作了,接着就开学,可能会减慢看《挑战程序设计竞赛(第2版)》的速度了。

知识共享许可协议 知识共享署名-非商业性使用-相同方式共享码农场 » POJ 2392 Space Elevator 题解 《挑战程序设计竞赛(第2版)》

评论 欢迎留言

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

我的作品

HanLP自然语言处理包《自然语言处理入门》