题目:
Leo是一个快乐的火星人,总是能和地球上的OIers玩得很high。
2012到了,Leo又被召回火星了,在火星上没人陪他玩了,但是他有好多好多积木,于是他开始搭积木玩。
火星人能制造n种积木,积木能无限供应。每种积木都是长方体,第i种积木的长、宽、高分别为li、wi、hi。积木可以旋转,使得长宽高任意变换。Leo想要用这些积木搭一个最高的塔。问题是,如果要把一个积木放在另一个积木上面,必须保证上面积木的长和宽都严格小于下面积木的长和宽。这意味着,即使两块长宽相同的积木也不能堆起来。
火星上没有电脑,好心的你决定帮助Leo求出最高的塔的高度。
【提示】
每种积木都可以拆分成高度分别为li、wi、hi的三种积木,另两边作为长和宽,保证长>=宽。
输入:
第一行,一个整数n,表示积木的种数
接下来n行,每行3个整数li,wi,hi,表示积木的长宽高
输出:
一行一个整数,表示塔高的最大值
样例输入:
1
10 20 30
样例输出:
40
思路:
先搞长宽高的组合,就一个全排列就好了,然后再排序DP
C o d e Code Code:
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int n,x,y,z,t,ans=-127 / 3;//初始化(方便取max)
int dp[1000001],h[1000001];
struct node
{
int chang,kuan,gao;//分别指长宽高(别告诉我你不会拼音)
}e[1000001];
bool cmp (node x,node y)
{
return x.chang < y.chang;
}//按长排序
int main ()
{
scanf("%d",&n);
for (int i = 1; i <= n; ++i)
{
scanf("%d%d%d",&x,&y,&z);
if (x > y) swap(x, y);//全排列
if (y > z) swap(y, z);
if (x > y) swap(x, y);
e[++t].chang = x,//每种用邻接表存一存~~
e[t].kuan=y,
e[t].gao=z;
e[++t].chang = x,
e[t].kuan=z,
e[t].gao=y;
e[++t].chang = y,
e[t].kuan=z,
e[t].gao=x;
}
sort(e + 1, e + 1 + t, cmp);
for (int i = 1; i <= t; ++i)
{
dp[i] = e[i].gao;//高
for (int j = 1; j < i; ++j)//暴力匹配
{
if (e[i].chang > e[j].chang && e[i].kuan > e[j].kuan)//符合长和宽的条件
dp[i] = max (dp[i], dp[j] + e[i].gao);
}
ans = max(ans,dp[i]);//更高的
}
printf("%d",ans);
return 0;
}