标签:
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://www.cnblogs.com/yxwkf/p/4728431.html