【DP】Leo搭积木

Leo搭积木

题目

Leo是一个快乐的火星人,总是能和地球上的OIers玩得很high。
2012到了,Leo又被召回火星了,在火星上没人陪他玩了,但是他有好多好多积木,于是他开始搭积木玩。
火星人能制造n种积木,积木能无限供应。每种积木都是长方体,第i种积木的长、宽、高分别为li、wi、hi。积木可以旋转,使得长宽高任意变换。Leo想要用这些积木搭一个最高的塔。问题是,如果要把一个积木放在另一个积木上面,必须保证上面积木的长和宽都严格小于下面积木的长和宽。这意味着,即使两块长宽相同的积木也不能堆起来。
火星上没有电脑,好心的你决定帮助Leo求出最高的塔的高度。

【提示】
每种积木都可以拆分成高度分别为li、wi、hi的三种积木,另两边作为长和宽,保证长>=宽。

输入

第一行,一个整数n,表示积木的种数
接下来n行,每行3个整数li,wi,hi,表示积木的长宽高

输出

一行一个整数,表示塔高的最大值

输入样例

#1

1
10 20 30

#2

2
6 8 10
5 5 5

#3

5
31 41 59
26 53 58
97 93 23
84 62 64
33 83 27

输出样例

#1

40

#2

21

#3

3420

数据范围

对于30%的数据 n<=8
对于100%的数据 n<=3000,最后答案不会超过32位整型

解题思路

其实这道题就是一道DP,

程序如下

#include
#include
#include
#include
using namespace std;
int n,x,y,z,a[100001],k,ans;
struct node
{
	int c,k,g;
}f[100001];

bool cmp(node xx,node yy)
{
	return xx.k < yy.k;
}
int main()
{
    scanf("%d",&n);
    for(int i = 1;i <= n; ++i)
    {
    	scanf("%d%d%d",&x,&y,&z);
    	
    	if(x >= y) f[++k] = (node){x,y,z}; //把每一种情况给存入数组
    	if(x >= z) f[++k] = (node){x,z,y}; 
    	if(y >= x) f[++k] = (node){y,x,z}; 
    	if(y >= z) f[++k] = (node){y,z,x}; 
    	if(z >= x) f[++k] = (node){z,x,y}; 
    	if(z >= y) f[++k] = (node){z,y,x}; 
    }
    sort(f + 1,f + 1 + k,cmp);
    for(int i = 1;i <= k; ++i)
		a[i] = f[i].g;
	for(int i = k;i >= 1; --i)
	{
		for(int j = i + 1;j <= k; ++j)
		{
			if(f[i].c < f[j].c && f[i].k != f[j].k)//判断是否为最优的
			a[i] = max(a[j] + f[i].g,a[i]);
		}
	}
	for(int i = 1;i <= k; ++i)
	   ans = max(ans,a[i]);
	printf("%d",ans); 
	return 0;
}

你可能感兴趣的:(DP)