L e o 搭 积 木 Leo搭积木 Leo搭积木
题目
L e o Leo Leo是一个快乐的火星人,总是能和地球上的 O I e r s OIers OIers玩得很 h i g h high high。
2012 2012 2012到了, L e o Leo Leo又被召回火星了,在火星上没人陪他玩了,但是他有好多好多积木,于是他开始搭积木玩。
火星人能制造 n n n种积木,积木能无限供应。每种积木都是长方体,第i种积木的长、宽、高分别为 l i l_i li、 w i w_i wi、 h i h_i hi。积木可以旋转,使得长宽高任意变换。 L e o Leo Leo想要用这些积木搭一个最高的塔。问题是,如果要把一个积木放在另一个积木上面,必须保证上面积木的长和宽都严格小于下面积木的长和宽。这意味着,即使两块长宽相同的积木也不能堆起来。
火星上没有电脑,好心的你决定帮助 L e o Leo Leo求出最高的塔的高度。
输入
第一行,一个整数
n
n
n,表示积木的种数
接下来
n
n
n行,每行
3
3
3个整数
l
i
l_i
li,
w
i
w_i
wi,
h
i
h_i
hi,表示积木的长宽高
输出
一行一个整数,表示塔高的最大值
样例输入1
1
10 20 30
样例输出1
40
样例输入2
2
6 8 10
5 5 5
样例输出2
21
样例输入3
5
31 41 59
26 53 58
97 93 23
84 62 64
33 83 27
样例输出3
342
数据范围
对于
30
%
30\%
30%的数据
n
<
=
8
n<=8
n<=8
对于
100
%
100\%
100%的数据
n
<
=
3000
n<=3000
n<=3000,最后答案不会超过
32
32
32位整型
思路
这道题同
d
p
dp
dp来做。
我们读入后,枚举每一个积木的摆放方法(要加一个长大于等于宽的条件),记录下去。
然后按宽从小到大排序,然后就
d
p
dp
dp求出最高可以摆的长度,就可以了。
代码想·
#include<cstdio>
#include<algorithm>
#define max(x, y) (x) > (y) ? (x) : (y)
using namespace std;
int n, x, y, z, k, f[100001], ans;
struct note {
int x, y, high;
}a[9001];
bool cmp(note x, note y) {
return x.y < y.y;
}
int main() {
scanf("%d", &n);//读入
for (int i = 1; i <= n; i++) {
scanf("%d %d %d", &x, &y, &z);//读入
if (x >= y) a[++k] = (note){x, y, z};//记录每一种摆法(在长大于等于宽的情况下)
if (x >= z) a[++k] = (note){x, z, y};
if (y >= x) a[++k] = (note){y, x, z};
if (y >= z) a[++k] = (note){y, z, x};
if (z >= y) a[++k] = (note){z, y, x};
if (z >= x) a[++k] = (note){z, x, y};
}
sort(a + 1, a + k + 1, cmp);//按宽从小到大排序
for (int i = k; i >= 1; i--) {
f[i] = a[i].high;//初始化
for (int j = i + 1; j <= k; j++)
if (a[i].y != a[j].y && a[i].x < a[j].x) {//可以摆
f[i] = max(f[i], f[j] + a[i].high);//dp
ans = max(ans, f[i]);//求出最高长度
}
}
printf("%d", ans);//输出
return 0;
}