HDU 1069 Monkey and Banana 基础DP

时间:2023-03-09 01:09:19
HDU 1069 Monkey and Banana 基础DP

题目链接:Monkey and Banana

大意:给出n种箱子的长宽高。每种不限个数。可以堆叠。询问可以达到的最高高度是多少。
要求两个箱子堆叠的时候叠加的面。上面的面的两维长度都严格小于下面的。

简单的DP,依然有很多地发给当时没想到。比如优先级,比如这么简单粗暴的选择。

 /*
大意是。给出n种箱子的长宽高。每种不限个数。可以堆叠。询问可以达到的最高高度是多少。
要求两个箱子堆叠的时候叠加的面。上面的面的两维长度都严格小于下面的。 样例:
10 20 30
10 20
10 30
20 30
可以摆放的方法:10 20
20 30
高度: 30+10 = 40 /思路:把所有种类的箱子的每个面的两维长度都列出来。n<=30,那么,箱子的面个数<=90。然后按照要求来开始堆叠。
问题是。我应该怎么来找当前最符合条件的呢。从两维长度都最大的开始吗。下一个怎么对应呢。还是应该从面积最大的开始。可能性太多。
以上出自无厘头系列。
/ 思路:给出一种箱子可以看做是三个箱子。(完全相同的两个面是不可能出现两次的。所以一个箱子最多会用三次、)。把所有的箱子按照先长后宽,从大到小排序。
然后(LIS。求最长递减子序列的思路。)dp[i] = j 表示从1到i的前i个(暂且当做从1开始)箱子里。在选第i个的前提下,得到的最大高度。
*/ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std; struct Node {
int x, y, z;
}node[]; // 最多90个 bool cmp(Node a, Node b) {
if (a.x != b.x)
return a.x < b.x;
else return a.y < b.y;
} int h[]; int main() {
int n;
int num = ;
while(~scanf("%d", &n)) {
if (n == ) break;
num++;
for (int j=, i=; j<n; ++j) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
node[i].x = a, node[i].y = b, node[i].z = c;
node[i+].x = a, node[i+].y = c, node[i+].z = b;
node[i+].x = b, node[i+].y = c, node[i+].z = a;
i += ;
} for (int i=; i<n*; ++i) {
if (node[i].x < node[i].y) {
int temp = node[i].y;
node[i].y = node[i].x;
node[i].x = temp;
}
} sort(node, node+n*, cmp);
int ans = -; for (int i=; i<*n; ++i) {
h[i] = node[i].z;
for (int j=; j<i; ++j) {
if (node[j].x < node[i].x && node[j].y < node[i].y) {
h[i] = max(h[i], h[j]+node[i].z);
}
}
ans = max(ans, h[i]);
} printf("Case %d: maximum height = %d\n", num, ans);
}
return ;
}