HDU Monkey and Banana 动态规划

来源:互联网 发布:持有期收益率知乎 编辑:程序博客网 时间:2024/05/17 03:48

Monkey and Banana

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 12486    Accepted Submission(s): 6527


Problem Description
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
 

Source
University of Ulm Local Contest 1996
 

Recommend
JGShining

    歇了好些天了,是时候开始好好敲代码了。
    题意:用n块不同的方块,每个方块有其长宽高,搭建木块的规则是下面的木块的长和宽必须各自都比上面木块的长和宽大,求最终搭起来的木块的最大高度,每块木块都可以无限次取用。
    分析:该题是类似于最大上升子序列的动态规划的问题。以题目中的第一个例子来说,长宽高为10,20,30中排列,选取一个长为20宽为30的木块,在其上面搭建一个长为10宽为20,这样最终搭成的木块的高度为10+30=40。
    这样每个方块单论长宽高的不同安排的话有六种方式,但该题只需要关心高度,所以长宽是可以对调的,每一种长宽高的木块有三种放置方式。建立一个block数组存储。该题的dp数组,dp[i]是指以第i块木块为顶能达到的最大高度。该题的理解近似于确定了上层木块然后再考虑下层木块。首先需要将木块以非递增的顺序处理。
    然后既然是动态规划问题,最关键的就是dp方程,该题的dp方程就是dp[i]=max{dp[j]+block[i].c,dp[i]},j从0——i-1取值,dp[i]初始值设置为木块的高度。理解:确定以第i块木块为顶,确定以j为i下一块的选择中最大的,相当于一个逐次确定下一块的思想。因为已经进行排序处理,所以block[0]——block[i-1]都是比第i快面积大,相当于一个预处理。最终求得所有的dp[i]取出其中最大的即为所求最大高度。
    见AC代码:
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int maxn=100;struct Block{int l,w,h;//l为长  w为宽  h为高int area;} block[maxn];int dp[maxn];int cmp(Block ba,Block bb){return ba.area>bb.area;}int main(){int n,k;while(~scanf("%d",&n)){k++;if(!n)break;memset(dp,0,sizeof(dp));int j=0,l,w,h,res=0;for(int i=0; i<n; i++){scanf("%d%d%d",&l,&w,&h);block[j].l=l;block[j].w=w;block[j].h=h;block[j].area=l*w;j++;block[j].l=l;block[j].w=h;block[j].h=w;block[j].area=l*h;j++;block[j].l=w;block[j].w=h;block[j].h=l;block[j].area=w*h;j++;}sort(block,block+3*n,cmp);//数组block[0] 为最大面积的砖块 以它为顶  没有木块可以放在它的下面 所以最高高度为它的高度dp[0]=block[0].h;for(int i=1; i<3*n; i++)dp[i]=block[i].h;//初始化for(int i=1; i<3*n; i++)for(int j=0; j<i; j++)//可以节约一半的空间 if((block[j].l>block[i].l&&block[j].w>block[i].w)||(block[j].l>block[i].w&&block[j].w>block[i].l))if(dp[j]+block[i].h>dp[i])dp[i]=dp[j]+block[i].h;for(int i=0; i<3*n; i++)res=max(res,dp[i]);printf("Case %d: maximum height = %d\n",k,res);}}
    看到题目虽然有一点思路,但是还不是很熟练,dp这一方面需要下大功夫好好练一练,唯有多刷题多思考。
    特记下,以备后日回顾。




0 0
原创粉丝点击