三维最长上升子序列问题——HDU 1069 Monkey and Banana

来源:互联网 发布:自己实现java虚拟机 编辑:程序博客网 时间:2024/05/22 04:56

题目:
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.

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

110 20 3026 8 105 5 571 1 12 2 23 3 34 4 45 5 56 6 67 7 7531 41 5926 53 5897 93 2384 62 6433 83 270

Sample Output

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

md,题目那么长,昨天读了半天才懂,然后调一晚上才a过去。

分析:

其实这题和我之前做的一个矩形嵌套十分类似。但是有两个很大的区别就是:
1.这里是求高度最高,而矩形嵌套是求矩形最多的个数。
2.这里的长方体每一个型号是可以选多个的(看你怎么摆了,总之一个长方体可有6中方式摆放)情况较多,而矩形嵌套只能给定多少个矩形就多少个,并且只有长和宽,简单得不行。

依然是DP的思想,通过转换成最长上升子序列的问题。
令长方体的三个棱长为x,y,z,那么有多少种方式摆放呢?

      长    宽    高    1 x     y     z    2 y     x     z    3 x     z     y    4 z     x     y    5 y     z     x    6 z     y     x

所以有六种,也就是说每一个长方体最多可拿6个,再多拿,怎么摆都会和之前拿的重复。那么我们就用一个数组保存3个输入的值,则只需枚举长和宽即可,高就是数组中的另外一个数。然后放到一个新的数组里(这个数组用定义的长方体结构体定义),最后就和矩形嵌套的方法一样了,注意要先sort一下,重写一下cmp即可,这样高度才能达最高。

细节:这里长和宽可以颠倒,即全排列,因为我之前一直用矩形嵌套的思想,只要长大于宽就行,所以我当时确定一个长方体最多拿3个,可这是三维的,所以我傻b了,就因为这个调了我一个小时QAQ。

代码:

#include<cstdio>#include<cstring>#include<algorithm> using namespace std;const int maxn = 200;int dp[maxn];int n;/*声明长方体结构体,为了保存输入数据*/struct Rec{    int r[3];}rec[30+5];/*声明新长方体结构体,为了摆放方式*/struct Rec_n{    int x,y;    int height;}rec_n[maxn];/*结构体类型数组排序*/int cmp(const Rec_n &a, const Rec_n &b){    if(a.x<b.x) return 1;    else if(a.x==b.x&&a.y<b.y) return 1;    else return 0;}/*DP*/int solve(){    int res = 0;    for(int i=0; i<n*6; i++)    {        dp[i] = rec_n[i].height;        for(int j=0; j<i; j++)        {            if((rec_n[i].x > rec_n[j].x) && (rec_n[i].y > rec_n[j].y))            {                dp[i] = max(dp[i], dp[j] + rec_n[i].height);            }        }        res = max(res, dp[i]);    }    return res;}int main(){    int ca = 1;    while(scanf("%d",&n)==1&&n)    {        for(int i=0; i<n; i++)        {            scanf("%d%d%d",&rec[i].r[0], &rec[i].r[1], &rec[i].r[2]);        }        int k=0;        for(int i=0; i<n; i++)        {                Rec_n r1,r2,r3,r4,r5,r6;//6种摆放方式                r1.x = rec[i].r[0]; r1.y = rec[i].r[1]; r1.height = rec[i].r[2];                rec_n[k++] = r1;                r2.x = rec[i].r[0]; r2.y = rec[i].r[2]; r2.height = rec[i].r[1];                rec_n[k++] = r2;                r3.x = rec[i].r[1]; r3.y = rec[i].r[2]; r3.height = rec[i].r[0];                rec_n[k++] = r3;                r4.x = rec[i].r[1]; r4.y = rec[i].r[0]; r4.height = rec[i].r[2];                rec_n[k++] = r4;                r5.x = rec[i].r[2]; r5.y = rec[i].r[0]; r5.height = rec[i].r[1];                rec_n[k++] = r5;                r6.x = rec[i].r[2]; r6.y = rec[i].r[1]; r6.height = rec[i].r[0];                rec_n[k++] = r6;        }        sort(rec_n,rec_n+n*6,cmp);        printf("Case %d: maximum height = %d\n",ca++,solve());    }    return 0;}//AC
0 0
原创粉丝点击