Monkey and Banana HDU - 1069

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

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

首先对这道题进行分析,要求上部尺寸严格小于底座尺寸,也就是说垒在上面的长方体的底座长宽都小于它下方的底座长宽。接下来分析样例1 10 20 30  高度为1底座长宽20*30高为10,下一层长宽为10*20 高为30,总的高度为40. 2 6 8 10 5 5 5,第一个底座为8*10,高为6,第一层为6*8 高为10,第二层底座为5*5,高为5,总的高度为6+10+5=21.这就是样例,接下来思考这是不是经典模型的变形。类似于最大上升子序列问题。接下来确定状态,分析动态规划方程。dp[i]=max{dp[j]+point[i].h,dp[i]};注意考虑边界问题dp[i]以第i块木块为顶,j为它的下一块,j0到i-1,要先进行排序预处理,这样block[0]就是排序好的最大的木块,接下来次之。

但是我有一个问题,本来长宽高有3!种排列方式,但是这道题它只关心高度,所以长宽是可以调换的,那应该是长宽高,长高宽,高长宽三种。但是这样子输出结果是错误的,只能是长宽高,长高宽,宽高长。我不知道这时为什么?????

刚才请教了大佬,懂了例如现在要求长必须大于宽,3,4,5,三个数:

长      宽        高

5        4           3

4        3            5

5         3           4

只要这样排列才可以,注意是把排列好的存在数组里面。   

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int dp[180];//30*6方向
struct Point
{
  int a,b,c;
  int area;
}point[180];
bool cmp(Point a,Point b)
{
  return a.area>b.area;
}
int main()
{
  int n,cnt=0,ans;
  while(cin>>n&&n!=0)
  {
    ans=0;
    cnt++;//为了以后的case
    memset(dp,0,sizeof(dp));
    int a,b,c,j=0;
    for(int i=0;i<n;i++)
    {
      scanf("%d%d%d",&a,&b,&c);
      //本来按理来说,有六种情况,因为有三个数为3!
      //注意n!和2^n    2^n为子集  n!为排列组合不重复
      //本来有六种情况,但是因为只考虑高度,长宽可以互换所以列举
      //三种情况
      point[j].a=a;
      point[j].b=b;
      point[j].c=c;
      point[j].area=a*b;
      j++;
      point[j].a=a;
      point[j].b=c;
      point[j].c=b;
      point[j].area=a*c;
      j++;
      point[j].a=b;
      point[j].b=c;
      point[j].c=a;
      point[j].area=b*c;
      j++;
    }
    sort(point,point+3*n,cmp);
    dp[0]=point[0].c;//排序后就是最高值
    for(int i=1;i<3*n;i++)
    {
      dp[i]=point[i].c;//初始化
    }
    for(int i=1;i<3*n;i++)
    {
      for(int j=0;j<i;j++)
      {
        if(((point[j].a>point[i].a)&&(point[j].b>point[i].b))||
           ((point[j].a>point[i].b)&&(point[j].b>point[i].a)))
           {
             if(dp[j]+point[i].c>dp[i])
             {
               dp[i]=dp[j]+point[i].c;
             }
           }
      }
    }
    for(int i=0;i<3*n;i++)
    {
      ans=max(ans,dp[i]);
    }
    printf("Case %d: maximum height = %d\n",cnt,ans);
  }
  return 0;
}

总的来说思路就是,认准模型。分析状态,思考方法,以及如何处理数据。

猜你喜欢

转载自blog.csdn.net/cjh1459463496/article/details/88900746
今日推荐