Case 4: maximum height = 342
题目大意:屋顶上放有香蕉,猴子有N块长宽高分别为x*y*z的砖。猴子想要
垒一座砖塔去吃香蕉。垒塔的时候上边的砖必须严格的比下边的砖小(上边砖
长<下边砖长 && 上边砖宽<下边砖宽)。砖有无数块,问最高能垒多高。
思路:虽然砖有无数块。但是长为x宽为y规模的砖只能用一块。因为上下砖
长和宽都不等。但是一块砖有好多种放法。这里先对x,y,z递增排序。建
一个结构体存摆放方法。让x为宽,y为长,z为高为一种摆法,让x为宽,z为
长,y为高为一种摆法,y为宽,z为长,x为高为第三种摆法。
这里为什么不将长宽调换位置来作为一种摆法?
其实是没必要这样。加上也对,不加也不会错。
因为上下砖的长宽是严格不等的。若让x为长,y为宽,z为高。
假设x,y,z的长度都不一样。则根据上边三种摆法。
最下边的砖为宽为y,长为z,高为x的砖。
在往上的砖为宽为x,长为y,高为z的砖。
另一块砖不能摆放。
加上y为宽,x为长,z为高的砖后。不能摆放。
同理,其他两种摆放方法也不成立。
把所有砖的摆放方法存起来之后,对砖的底面面积(长*宽)进行升序排列。
之后就是类似求最长递增子序列的最大和了。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct block
{
int x;
int y;
int z;
int area;
}Block[330];
int dp[330];
int cmp(block a,block b)
{
return a.area < b.area;
}
int main()
{
int N,a[3],kase = 1;
while(~scanf("%d",&N) && N)
{
int num = 0;
memset(dp,0,sizeof(dp));
memset(Block,0,sizeof(Block));
for(int i = 0; i < N; i++)
{
scanf("%d%d%d",&a[0],&a[1],&a[2]);
sort(a,a+3);
Block[num].x = a[0],Block[num].y = a[1],Block[num].z = a[2],Block[num].area = Block[num].x*Block[num].y,num++;
Block[num].x = a[1],Block[num].y = a[2],Block[num].z = a[0],Block[num].area = Block[num].x*Block[num].y,num++;
Block[num].x = a[0],Block[num].y = a[2],Block[num].z = a[1],Block[num].area = Block[num].x*Block[num].y,num++;
}
sort(Block,Block+num,cmp);
int Max = 0;
for(int i = 0; i < num; i++)
{
dp[i] = Block[i].z;
for(int j = 0; j < i; j++)
{
if(Block[j].x < Block[i].x && Block[j].y < Block[i].y)
dp[i] = max(dp[i],dp[j]+Block[i].z);
}
Max = max(dp[i],Max);
}
printf("Case %d: maximum height = %d\n",kase++,Max);
}
return 0;
}
HDU1069_Monkey and Banana【LCS】
原文:http://blog.csdn.net/lianai911/article/details/40346621