HDU 1069 Monkey and Banana(最大递增子串)

题目链接: [kuangbin带你飞]专题十二 基础DP1 C - Monkey and Banana

** 题意 **

给定箱子种类数量n,及对应长宽高,每个箱子数量无限,求其能叠起来的最大高度是多少(上面箱子的长宽严格小于下面箱子)

** 思路 **

每种箱子有三种放置方式且数量无限,故可将每个箱子按三个箱子看待。对所有箱子按主长副宽进行先大后小排序,那么问题就成了求最大递增子串。
因为n的范围特别小,只有30,所以直接两重循环dp即可

** 代码 **

#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<stack>
#include<queue>
using namespace std;

const int N = 39;
struct Node
{
    int a, b, c;
    bool operator < (const Node &t) const
    {
        if(a == t.a)
            return b > t.b;
        return a > t.a;
    }
}node[N*3];
int dp[N*3];

void add(int i, int a, int b, int c)
{
    node[i].a = a;
    node[i].b = b;
    node[i].c = c;
}

int main()
{
    int n, T = 1;
    while(~scanf("%d", &n) && n)
    {
        for(int i=0; i<n; i++)
        {
            int a, b, c;
            scanf("%d%d%d", &a, &b, &c);
            add(i*3, max(a, b), min(a, b), c);
            add(i*3+1, max(a, c), min(a, c), b);
            add(i*3+2, max(c, b), min(c, b), a);
        }
        sort(node, node+n*3);
        dp[0] = node[0].c;
        int ans = dp[0];
        for(int i=1; i<3*n; i++)
        {
            int temp = 0;
            dp[i] = node[i].c;
            for(int j=0; j<i; j++)
            {
                if(node[i].a<node[j].a && node[i].b<node[j].b)
                    temp = max(temp, dp[j]);
            }
            dp[i] += temp;
            ans = max(ans, dp[i]);
        }
        printf("Case %d: maximum height = %d\n", T++, ans);
    }
    return 0;
}