HDU 1069 堆叠箱子

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. 

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

题目大意:

一堆科学家研究猩猩的智商,给他M种长方体,每一种有无限多个。

然后,将一个香蕉挂在屋顶,让猩猩通过 叠长方体来够到香蕉。

现在给你M种长方体,计算,最高能堆多高。要求位于上面的长方体的长要大于(注意不是大于等于)下面长方体的长,上面长方体的宽大于下面长方体的宽。

思路:求最大化的问题,那就是差不多就是DP了,这道题有一个条件,就是每种长方体,下面就叫做箱子吧,虽然有不限多个,但是还有一个要求就是箱子堆叠的时候下面的箱子的上表面的长与宽都是大于上面箱子对应的长与宽(长不一定是大于宽的),满足这个条件的话,那么三条边,我们可以得到2*3种长宽高的箱子,题目n<=30,那最多开一个30*6的数组当做DP数组,然后就是找递推关系式了,我们先将这里的长宽进行排列使长从大到小排列,如果长一样的话,就将宽从大到小排列,这样的话就可以写出DP的递推关系式了:

dp[i]=max(dp[k])+num[i].h(0<=k<=i-1);

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define ms(a,b) memset(a,b,sizeof a)
const int mod = 1e9;
const int maxn = 1e6 + 10;
int n,m;
int dp[200];
struct node
{
    int l,w,h;
}num[200];
bool cmp(node a,node b)
{
    if(a.l==b.l)
        return a.w>b.w;//不用排宽也是可以的
    return a.l>b.l;
}
int main() {
    int n;
    int T=1;
    while(scanf("%d",&n)!=EOF,n)
    {
        ms(dp,0);ms(num,0);
        int x,y,z;
        int sum=0;
        ms(dp,0);
        rep(i,1,n)
        {
        scanf("%d%d%d",&x,&y,&z);
        num[sum].l=x,num[sum].w=y,num[sum++].h=z;
        num[sum].l=y,num[sum].w=x,num[sum++].h=z;
        num[sum].l=z,num[sum].w=y,num[sum++].h=x;
        num[sum].l=y,num[sum].w=z,num[sum++].h=x;
        num[sum].l=x,num[sum].w=z,num[sum++].h=y;
        num[sum].l=z,num[sum].w=x,num[sum++].h=y;
        }
    sort(num,num+sum,cmp);
    dp[0]=num[0].h;//先将第一个值放入到dp[0]当中,在这里dp数组表示的是前i种能够达到的最大高度
    rep(i,1,sum-1)
    {
        int maxx=-maxn;
        maxx=0;
        rep(j,0,i-1)
        {//因为存储的长宽都是从大到小的顺序排列的,因此最大的底面,也就是当前的最底层就是dp[i]
        //然后就需要将长宽都比这个底层小的元素的高找到,然后取最大值加入到dp[i]中;
            if(num[i].l<num[j].l&&num[i].w<num[j].w)
            maxx=max(maxx,dp[j]);
        }
        dp[i]=maxx+num[i].h;
    }
    printf("Case %d: maximum height = ",T++);
    //我们是无法确定dp数组最高的值是以哪一个底面搭建的,因此需要取一下最大值
    printf("%d\n",*max_element(dp,dp+sum));
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/c___c18/article/details/82499287