算法竞赛入门经典 例题9-2

本文介绍了解决UVa00437问题——The Tower of Babylon的一种动态规划方法。该问题涉及堆叠不同尺寸的立方体以达到最大高度,同时确保上层立方体的尺寸严格小于下层立方体。通过将每个立方体转换为三种可能的放置方式,并使用动态规划算法来找到最优解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

UVa 00437

The Tower of Babylon

有长宽高分别为x[i]y[i]z[i]的立方体,每种的数量有无限个,求摞起后能得到的最大高度,限制条件是上面立方体底面的长和宽严格小于下面立方体顶面的长和宽。

比较简单的一道动态规划题目,只需要将立方体依次摞上去就可以了,但是要注意的就是如何表示状态,还是需要和上一道一样进行转化,这里我将n的立方体变成了3 * n个立方体。

#include <iostream>
#include <vector>

using namespace std;

struct Cube
{
	int length, width, height;
	Cube(const int &l, const int &w, const int &h)
		:length(l), width(w), height(h) {}
};

bool placeable(int a, int b, int c, int d)
{
	return (a < c && b < d) || (a < d && b < c);
}

int calMaxHeight(const vector<Cube> &vcCube)
{
	vector<int> viHeight;
	for (auto iter = vcCube.begin(); iter != vcCube.end(); iter++)
	{
		viHeight.push_back(iter->height);
	}
	bool bUpdate = true;
	while (bUpdate) {
		bUpdate = false;
		for (size_t i = 0; i < vcCube.size(); i++)
		{
			for (size_t j = 0; j < vcCube.size(); j++)
			{
				if (i == j) continue;
				if (placeable(vcCube[j].length, vcCube[j].width,
					vcCube[i].length, vcCube[i].width)) {
					if (viHeight[j] < viHeight[i] + vcCube[j].height) {
						viHeight[j] = viHeight[i] + vcCube[j].height;
						bUpdate = true;
					}
				}
			}
		}
	}
	int maxHeight = 0;
	for (size_t i = 0; i < viHeight.size(); i++)
	{
		if (viHeight[i] > maxHeight) {
			maxHeight = viHeight[i];
		}
	}
	return maxHeight;
}

int main()
{
	int Case = 0, n;
	while (cin >> n) {
		if (n == 0) break;
		vector<Cube> vcCube;
		int x, y, z;
		for (int i = 0; i < n; i++)
		{
			cin >> x >> y >> z;
			vcCube.push_back(Cube(x, y, z));
			vcCube.push_back(Cube(x, z, y));
			vcCube.push_back(Cube(y, z, x));
		}
		cout << "Case " << ++Case << ": maximum height = ";
		cout << calMaxHeight(vcCube) << endl;
	}
	return 0;
}
/*
1
10 20 30
2
6 8 10
5 5 5
7
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
5
31 41 59
26 53 58
97 93 23
84 62 64
33 83 27
0
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值