HDU 1069 Monkey and Banana

题意:
给你n种箱子的长、宽、高,他们可以一个摞另一个上面来组成一个塔,上面箱子的长宽必须严格小于下面箱子的长宽,每种箱子数量无限,问塔最高能达到多高。

思路:
最开始以为是搜索,但是算了一下状态有太多,虽然可以存是否用过边,但是思路一直比较混乱。
其实把每种箱子当成3种箱子就可以,分别有3种不同的长宽组合,那么这3种箱子的价值就是高了。
把所有的箱子长宽组合遍历出来,然后再对长宽排从小到大排序,那么此箱子能达到的最大价值就等于能摞在此箱子上的最大价值加上此箱子本身的价值。
也就是说:

f[i] 代表以i箱子为底能摞起的最大高度
那么f[i] = i1k=0f[k] (a[k] < a[i] && b[k] < a[i])
(a[i]和b[i]分别代表长和宽)
anwser = n1i=0max(f[i])

Code:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<bitset>
#include<queue>
#include<stack>
#include<list>
#include<map>
#include<set>

#define TEST

#define LL long long
#define Mt(f, x) memset(f, x, sizeof(f));
#define rep(i, s, e) for(int i = (s); i <= (e); ++i)
#ifdef TEST
    #define See(a) cout << #a << " = " << a << endl;
    #define See2(a, b) cout << #a << " = " << a << ' ' << #b << " = " << b << endl;
    #define debug(a, s, e) rep(_i, s, e) {cout << a[_i] << ' ';} cout << endl;
    #define debug2(a, s, e, ss, ee) rep(i_, s, e) {debug(a[i_], ss, ee)}
#else
    #define See(a)
    #define See2(a, b)
    #define debug(a, s, e)
    #define debug2(a, s, e, ss, ee)
#endif // TEST

const int MAX = 2e9;
const int MIN = -2e9;
const double eps = 1e-8;
const double PI = acos(-1.0);

using namespace std;

const int N = 35;

struct Node
{
    int a;
    int b;
    int c;
    Node(){}
    Node(int ta, int tb, int tc)
    {
        a = min(ta, tb);
        b = max(ta, tb);
        c = tc;
    }
}e[N * 3];

int n, f[N * 3];

bool cmp(Node a, Node b)
{
    if(a.a != b.a)
    {
        return a.a < b.a;
    }
    return a.b < b.b;
}

int main()
{
    int _ = 1;
    while(~scanf("%d", &n) && n)
    {
        Mt(f, 0);
        int a, b, c;
        for(int i = 0;i < n; ++i)
        {
            scanf("%d%d%d", &a, &b, &c);
            e[i * 3] = Node(a, b, c);
            e[i * 3 + 1] = Node(a, c, b);
            e[i * 3 + 2] = Node(b, c, a);
        }
        sort(e, e + n * 3, cmp);
        int ans = MIN;
        for(int i = 0; i < n * 3; ++i)
        {
            f[i] = e[i].c;
            for(int k = 0; k < i; ++k)
            {
                if(e[k].a < e[i].a && e[k].b < e[i].b)
                {
                    f[i] = max(f[i], e[i].c + f[k]);
                }
            }
            ans = max(f[i], ans);
        }
        printf("Case %d: maximum height = %d\n", _++, ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值