HDOJ-1069 Monkey and Banana(动态规划)

版权声明:个人学习笔记记录 https://blog.csdn.net/Ratina/article/details/84959661

链接:HDOJ-1069

Problem Description

A group of researchers are designing an experiment to test the IQ of amonkey. They will hang a banana at the roof of a building, and at the mean time, provide the monkey with some blocks. If the monkey is clever enough, it shall be able to reach the banana by placing one block on the top another to build a tower and climb up to get its favorite food.

The researchers have n types of blocks, and an unlimited supply of blocks of each type. Each type-i block was a rectangular solid with linear dimensions (xi, yi, zi). A block could be reoriented so that any two of its three dimensions determined the dimensions of the base and the other dimension was the height.

They want to make sure that the tallest tower possible by stacking blocks can reach the roof. The problem is that, in building a tower, one block could only be placed on top of another block as long as the two base dimensions of the upper block were both strictly smaller than the corresponding base dimensions of the lower block because there has to be some space for the monkey to step on. This meant, for example, that blocks oriented to have equal-sized bases couldn’t be stacked.

Your job is to write a program that determines the height of the tallest tower the monkey can build with a given set of blocks.

Input

The input file will contain one or more test cases. The first line of each test case contains an integer n,
representing the number of different blocks in the following data set. The maximum value for n is 30.
Each of the next n lines contains three integers representing the values xi, yi and zi.
Input is terminated by a value of zero (0) for n.

Output

For each test case, print one line containing the case number (they are numbered sequentially starting from 1) and the height of the tallest possible tower in the format “Case case: maximum height = height”.

Sample Input

1
10 20 30
2
6 8 10
5 5 5
7
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
5
31 41 59
26 53 58
97 93 23
84 62 64
33 83 27
0

Sample Output

Case 1: maximum height = 40
Case 2: maximum height = 21
Case 3: maximum height = 28
Case 4: maximum height = 342


题目大意:
给n种立方体,给定长宽高,使用时可以重定向,每种立方体无限供应。搭立方体时需保证上方立方体底面的长严格小于下方立方体底面的长,上方立方体底面的宽严格小于下方立方体底面的宽,问最多可以搭多高,求出最大高度。


思路:
每1种立方体都可以重定向为6种立方体(可能6种中有相同的,但并不会影响结果)。
这里设长为x,宽为y,高为h。
先按x从大到小排序(也可以按y)
之后就是寻找序列中符合x不相等y严格递减h之和最大子序列

那么动态规划的状态转移方程如下:
dp[i] = max( dp[a1] , dp[a2] , … , dp[an] ) + h[i]

a1,a2,…,an < i && x[a1],x[a2],…,x[an] != x[i] && y[a1],y[a2],…,y[an] < y[i]


#include<cstdio>
#include<algorithm>
using namespace std;
struct blocks
{
	int x;
	int y;
	int h;
};
bool cmp(blocks a,blocks b)
{
	if(a.x!=b.x)
		return a.x>b.x;
	else
		return a.y>b.y;
}
int main()
{
	int n,kase=0;
	while(scanf("%d",&n)&&n)
	{
		blocks a[200];
		int i,j,N=0,dp[200]={0};
		for(i=1;i<=n;i++)
		{
			int t1,t2,t3;
			scanf("%d%d%d",&t1,&t2,&t3);
			/*重定向*/
			N++;
			a[N].x=t1;
			a[N].y=t2;
			a[N].h=t3;
			N++;
			a[N].x=t1;
			a[N].y=t3;
			a[N].h=t2;
			N++;
			a[N].x=t2;
			a[N].y=t1;
			a[N].h=t3;
			N++;
			a[N].x=t2;
			a[N].y=t3;
			a[N].h=t1;
			N++;
			a[N].x=t3;
			a[N].y=t1;
			a[N].h=t2;
			N++;
			a[N].x=t3;
			a[N].y=t2;
			a[N].h=t1;
		}
		sort(a+1,a+N+1,cmp);
		int ans=0;
		for(i=1;i<=N;i++)
		{
			for(j=1;j<i;j++)
			{
				if(a[j].y>a[i].y&&a[j].x!=a[i].x)  //找到符合的接在i前面的最大dp[j]
					dp[i]=max(dp[i],dp[j]);
			}
			dp[i]+=a[i].h;        //记得加上a[i].h
			ans=max(ans,dp[i]);   //更新最大值
		}
		printf("Case %d: maximum height = %d\n",++kase,ans);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Ratina/article/details/84959661