HDU 1069 Monkey and Banana 解题心得

原题:

Description

一组研究人员正在设计一项实验,以测试猴子的智商。他们将挂香蕉在建筑物的屋顶,同时,提供一些砖块给这些猴子。如果猴子足够聪明,它应当能够通过合理的放置一些砖块建立一个塔,并爬上去吃他们最喜欢的香蕉。
 
研究人员有n种类型的砖块,每种类型的砖块都有无限个。第i块砖块的长宽高分别用xi,yi,zi来表示。 同时,由于砖块是可以旋转的,每个砖块的3条边可以组成6种不同的长宽高。
 
在构建塔时,当且仅当A砖块的长和宽都分别小于B砖块的长和宽时,A砖块才能放到B砖块的上面,因为必须留有一些空间让猴子来踩。
 
你的任务是编写一个程序,计算猴子们最高可以堆出的砖块们的高度。

Input

输入文件包含多组测试数据。
每个测试用例的第一行包含一个整数n,代表不同种类的砖块数目。n<=30.
接下来n行,每行3个数,分别表示砖块的长宽高。
当n= 0的时候,无需输出任何答案,测试结束。

Output

对于每组测试数据,输出最大高度。格式:Case 第几组数据: maximum height = 最大高度

Sample Input

1
10 20 30 

6 8 10 
5 5 5 

1 1 1 
2 2 2 
3 3 3 
4 4 4 
5 5 5 
6 6 6 
7 7 7 

31 41 59 
26 53 58 
97 93 23 
84 62 64 
33 83 27 

Sample Output

Case 1: maximum height = 40
Case 2: maximum height = 21 
Case 3: maximum height = 28 
Case 4: maximum height = 342 
 
 
分析:dp[i]=max( for(j=i-1;j>=0;j--)    dp[j]+block[i].h  ,dp[i] )
输入一组数组要存入6个数据,分别对应6中不同的摆放方式,(其实也可以只要存三组同时保证宽小于长)->排序->再用状态转移方程:
dp[i]  表示以第i个砖作为底部可以累加的最大高度
dp[i]=max( for(j=i-1;j>=0;j--)    dp[j]+block[i].h  ,dp[i] )
 
 
 
 
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;

//   状态转移方程:   dp[i]=max(        for(j=i-1;j>=0;j--)    dp[j]+block[i].h  ,dp[i] )
//  复杂度  n^2

struct blocks
{
    int a, b, h;
    bool operator <(const blocks &x)const
    {
        if (a == x.a){
            return b < x.b;
        }
        else{
            return a < x.a;
        }
    }
}block[200];
int dp[200];

bool check(const blocks &x, const blocks &y)
{
    if (x.a < y.a&&x.b < y.b)
        return 1;
    return 0;
}

//                    dp[i]  表示以第i个砖作为底部可以累加的最大高度
int main()
{
    int kase;
    int k = 1;
    while (cin >> kase&&kase != 0)
    {
        int x, y, z;
        int n = kase * 6;
        for (int i = 0; i < n;)
        {
            scanf("%d%d%d", &x, &y, &z);
            block[i].a = x, block[i].b = y, block[i].h = z, i++;
            block[i].a = x, block[i].b = z, block[i].h = y, i++;
            block[i].a = y, block[i].b = x, block[i].h = z, i++;
            block[i].a = y, block[i].b = z, block[i].h = x, i++;
            block[i].a = z, block[i].b = x, block[i].h = y, i++;
            block[i].a = z, block[i].b = y, block[i].h = x, i++;
        }
        sort(block, block + n);
        int Max = 0;
        for (int i = 0; i < n; i++)
        {
            dp[i] = block[i].h;
            for (int j = i - 1; j >= 0; j--)
            {
                if (check(block[j], block[i]) && dp[i] < dp[j] + block[i].h)
                    dp[i] = dp[j] + block[i].h;
            }
            if (Max < dp[i])
                Max = dp[i];

        }
        printf("Case %d: maximum height = %d\n", k++, Max);
    }



    return 0;
}

 

转载于:https://www.cnblogs.com/shawn-ji/p/4732779.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值