三维最长上升子序列问题——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
- 三维最长上升子序列问题——HDU 1069 Monkey and Banana
- HDU 1069 Monkey and Banana (最长上升子序列)
- hdu 1069 Monkey and Banana(dp 最长上升子序列)
- hdu 1069 Monkey and Banana 最长上升子序列。
- HDU 1069 Monkey and Banana 最长上升子序列模板
- HDU 1069 Monkey and Banana (dp, 最长上升子序列)
- hdu 1069 Monkey and Banana(类似最长上升子序列,dp)
- HDU 1069 Monkey and Banana(dp最长上升子序列)
- HDU 1069 Monkey and Banana dp类型:最长上升子序列
- hdu 1069 Monkey and Banana--最长递增子序列
- hdu 1069 monkey and banana(最长下降子序列)
- hdu 1069 Monkey and Banana(最长递减子序列 )
- HDU 1069 Monkey and Banana (类似最长递增子序列)
- Monkey and Banana (最长子序列)
- HDU Monkey and Banana 1069 dp 动态规划 最长递增子序列
- hdu 1069 Monkey and Banana(最长递增子序列的变形)
- 动态规划1:H - Monkey and Banana(最长非上升子序列)
- (DP,最长上升子序列变形)Monkey and Banana--HDOJ
- hiho1507 可疑的记录
- xx面试归来有感
- 买书
- Python while 循环
- 进程 线程笔记
- 三维最长上升子序列问题——HDU 1069 Monkey and Banana
- XSLT学习笔记
- Easy 7 Remove Duplicates from Sorted Array(26)
- Linux下配置jdk和tomcat环境后访问tomcat主页出现500的错误
- Android Ndk开发进阶
- Python 中文分词
- flask学习笔记1【服务器程序基本结构】
- how to write
- struts2--拦截器(非登录用户不可跳转至该页面)