Monkey and Banana(变形的最长递增序列)
问题描述:
A group of researchers are designing an experiment to test the IQ of a monkey. 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.
(一组研究人员正在设计一项测试猴子智商的实验。他们会在屋顶上挂一根香蕉,同时给猴子一些积木。如果猴子足够聪明,它应该能够够到香蕉,把一块放在另一块的顶部,建立一个塔,爬上去得到它最喜欢的食物。
研究人员有n种积木,每种积木都有无限的供应。每个i型块都是具有线性维度(习,yi, zi)的矩形实体。一块砖可以重新定向,这样它的三个维度中的任意两个都可以确定底部的维度,另一个维度是高度。
他们想通过堆叠积木来确保最高的塔能够达到屋顶。问题在于,在建立一个塔,一个块只能被放置在另一个块只要上层块的两个基本维度都严格小于相应的基本维度较低的块,因为必须有一些猴子踩空间。这意味着,例如,面向相同大小的基的块不能被堆叠。
你的工作是编写一个程序,确定猴子用给定的一组积木可以建造的最高的塔的高度。)
输入描述:
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.
(输入文件将包含一个或多个测试用例。每个测试用例的第一行包含一个整数n,
表示以下数据集中不同块的数量。n的最大值为30。接下来的n行每一行都包含三个整数,表示值习、yi和zi。对于n,输入以一个值0(0)结束。)
输出描述:
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”.
(对于每个测试用例,打印一行包含用例编号(从1开始依次编号)和可能最高的塔的高度,格式为“用例:maximum height = height”。)
样例输入:
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
样例输出:
Case 1: maximum height = 40
Case 2: maximum height = 21
Case 3: maximum height = 28
Case 4: maximum height = 342
AC代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <iostream>
using namespace std;
int dp[10010],ans[10010];
struct node
{
int x,y,id,f;
} mouse[10010];
bool cmp(node x,node y)
{
if(x.x!=y.x)return x.x<y.x;
return x.y>y.y;
}
int main()
{
int index=1,i,j;
while(~scanf("%d%d",&mouse[index].x,&mouse[index].y))
{
mouse[index].id=index;
mouse[index].f=0;
index++;
}
if(index==1)
{
printf("0\n");
return 0;
}
sort(mouse+1,mouse+index,cmp);
dp[1]=1;
for(i=1; i<index; i++)
{
dp[i]=1;
for(j=1; j<i; j++)
{
if(mouse[j].y>mouse[i].y&&mouse[j].x<mouse[i].x)
{
if(dp[j]+1>dp[i])
{
dp[i]=dp[j]+1;
mouse[i].f=j;
}
}
}
}
j=1;
for(i=2; i<index; i++)
if(dp[i]>dp[j])j=i;
printf("%d\n",dp[j]);
index=0;
while(mouse[j].f)
{
ans[index++]=mouse[j].id;
j=mouse[j].f;
}
printf("%d\n",mouse[j].id);
for(i=index-1; i>=0; i--)
printf("%d\n",ans[i]);
return 0;
}