题目链接:[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;
}