HDU-1069 Monkeys and Banana

版权声明:欢迎评论与转载,转载时请注明出处! https://blog.csdn.net/wjl_zyl_1314/article/details/83580905

原题
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
题意:
有n种木块,每一种木块都有长宽高,并且有无限多个,现在要求你用这些木块来搭积木,要求高度最高。搭积木的要求是,只有两个木块的接触面上边的那个长和宽都要小于在下边的木块的长和宽。搭积木的过程中可以调整每一个木块的角度,使其长宽高相互变换。
题解:
由于每一种木块都有无限个,且搭积木时可以调整角度,相当于可以衍生出来6种不同的积木,而又因为长宽即使相同也不能搭在上面,所以可以将无限个每种木块抽象出6个不同的木块,剩下的就是按照题目进行动态规划处理了:
dp【i】=max(dp【i】,dp【j】+high)
如果满足题意,并且此方法搭出的高度比原先搭出的高度要高,则记录新方法。
(更多细节见代码)
附上AC代码:

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
struct t
{
    int x,y,z;
}st[200];//定义结构体
int n,dp[200];
bool cmp(t a,t b)
{
    if(a.x==b.x)
        return a.y<b.y;
    return a.x<b.x;
}//按照x的大小从小到大排序
int main()
{
    int cas=1;
    while(cin>>n,n)
    {
        int x,y,z,k=0;
        for(int i=1;i<=n;++i)
        {
            cin>>x>>y>>z;
            /*
            因为说了每一种都有无限多个,并且可以颠倒顺序,
            有6中不同的组合方式,而且因为如果两个的面积完全相同也不能够踩上去,
            所以无限多个积木就可以想成以下6种木块且唯一存在
            */
            st[k].x=x,st[k].y=y,st[k++].z=z;
            st[k].x=x,st[k].y=z,st[k++].z=y;
            st[k].x=y,st[k].y=x,st[k++].z=z;
            st[k].x=y,st[k].y=z,st[k++].z=x;
            st[k].x=z,st[k].y=y,st[k++].z=x;
            st[k].x=z,st[k].y=x,st[k++].z=y;
        }
        sort(st,st+k,cmp);
        for(int i=0;i<k;++i)
        {
            dp[i]=st[i].z;//初始化每一个木块的起始高度
        }
        for(int i=0;i<k;i++)
        {
            //对于第i个木块在其之前的所有木块种找出最佳的排列组合使高度最高
            for(int j=0;j<i;j++)
            {
                if(st[i].x>st[j].x&&st[i].y>st[j].y&&dp[i]<dp[j]+st[i].z)
                //如果满足条件:长宽都比其大,并且放上去后比原先的方法的高度高
                    dp[i]=dp[j]+st[i].z;
            }
        }
        sort(dp,dp+k);//输出最大的那一个高度
        printf("Case %d: maximum height = %d\n",cas++,dp[k-1]);
    }
    return 0;
}

欢迎评论!

猜你喜欢

转载自blog.csdn.net/wjl_zyl_1314/article/details/83580905