【洛谷】UVA437 巴比伦塔 The Tower of Babylon

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


题目

一、原文

Perhaps you have heard of the legend of the Tower of Babylon. Nowadays many details of this tale

have been forgotten. So now, in line with the educational nature of this contest, we will tell you the

whole story:
The babylonians had n types of blocks, and an unlimited supply of blocks of each type.

Each type-i block was a rectangular solid with linear dimensions (xi
, yi, zi). A block could

be reoriented so that any two of its three dimensions determined the dimensions of the base

and the other dimension was the height.

They wanted to construct the tallest tower possible by stacking blocks. The problem was

that, in building a tower, one block could only be placed on top of another block as long as

the two base dimensions of the upper block were both strictly smaller than the corresponding

base dimensions of the lower block. This meant, for example, that blocks oriented to have

equal-sized bases couldn’t be stacked.

Your job is to write a program that determines the height of the tallest tower the babylonians can

build with a given set of blocks.

Input

The input file will contain one or more test cases. The first line of each test case contains an integer n,

representing the number of different blocks in the following data set. The maximum value for n is 30.

Each of the next n lines contains three integers representing the values xi
, yi and zi

.

Input is terminated by a value of zero (0) for n.

Output

For each test case, print one line containing the case number (they are numbered sequentially starting

from 1) and the height of the tallest possible tower in the format
‘Case case: maximum height = height’

Sample Input

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
Sample Output

Case 1: maximum height = 40
Case 2: maximum height = 21
Case 3: maximum height = 28
Case 4: maximum height = 342

二、译文

你可能已经听说过巴比伦塔的传说。现在这个传说的许多细节已经被遗忘。所以本着本场比赛的教育性质,我们现在会告诉你整个传说:

巴比伦人有n种长方形方块,每种有无限个,第i种方块的三边边长是xi,yi,zi。对于每一个方块,你可以任意选择一面作为底,这样高就随着确定了。举个例子,同一种方块,可能其中一个是竖着放的,一个是侧着放的,一个是横着放的。

他们想要用堆方块的方式建尽可能高的塔。问题是,只有一个方块的底的两条边严格小于另一个方块的底的两条边,这个方块才能堆在另一个上面。这意味着,一个方块甚至不能堆在一个底的尺寸与它一样的方块的上面。

你的任务是编写一个程序,计算出这个塔可以建出的最高的高度。

【输入】

输入会包含至少一组数据,每组数据的第一行是一个整数n(n<=30),表示方块的种类数。 这组数据接下来的n行,每行有三个整数,表示xi,yi,zi。 输入数据会以0结束。

【输出】

对于每组数据,输出一行,其中包含组号(从1开始)和塔最高的高度。按以下格式: Case : maximum height = __

【输入样例】

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

【输出样例】

Case 1: maximum height = 40

Case 2: maximum height = 21

Case 3: maximum height = 28

Case 4: maximum height = 342

输入输出样例
输入 #1复制
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
输出 #1复制
Case 1: maximum height = 40
Case 2: maximum height = 21
Case 3: maximum height = 28
Case 4: maximum height = 342


总结

那么代码就放到下面了

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
struct P {
	int w, d, h;
} p[200];
int a[5];
int n;
bool cmp(P a, P b) {
	if (a.w == b.w) {
		return a.d < b.d;
	}
	return a.w < b.w;
}
int f[200], ans = -1;
int main() {
	while (cin >> n && n) {
		ans = -1;
		memset(f, 0, sizeof(f));
		for (int i = 1; i <= n; i++) {
			cin >> a[0] >> a[1] >> a[2];
			p[i].w = a[0], p[i].d = a[1], p[i].h = a[2];
			p[i + n].w = a[0], p[i + n].d = a[2], p[i + n].h = a[1];
			p[i + n * 2].w = a[1], p[i + 2 * n].d = a[0], p[i + 2 * n].h = a[2];
			p[i + 3 * n].w = a[1], p[i + 3 * n].d = a[2], p[i + 3 * n].h = a[0];
			p[i + 4 * n].w = a[2], p[i + 4 * n].d = a[0], p[i + 4 * n].h = a[1];
			p[i + 5 * n].w = a[2], p[i + 5 * n].d = a[1], p[i + 5 * n].h = a[0];
		}
		sort(p + 1, p + 6 * n + 1, cmp);
		for (int i = 1; i <= 6 * n; i++) {
			f[i] = p[i].h;
			for (int j = 1; j < i; j++) {
				if (p[i].w > p[j].w && p[i].d > p[j].d) {
					f[i] = max(f[j] + p[i].h, f[i]);
				}
			}
			ans = max(f[i], ans);
		}
		cout << ans << endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

恒__heng

创作不易,能否鼓励我一下

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值