http://acm.hdu.edu.cn/showproblem.php?pid=1069
意思就是给定n种箱子,每种箱子都有无限个,每种箱子都是有三个参数(x, y, z)来确定。
你可以选任意两个参数作为长和宽,第三个是高。
然后要求把箱子搭起来,使得高度最高。
能搭的前提是下面那个箱子的长和宽都 > 上面那个箱子的。
思路:
因为同一个箱子可以产生6中不同的箱子,而每种最多选一个,因为相同的箱子最多只能搭起来一个。
那么可以把所有箱子都弄出来,排序,就是LIS的题目了。
dp[i]表示以i这个箱子为结尾的最大高度。
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #define IOS ios::sync_with_stdio(false) using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; #include <iostream> #include <sstream> #include <vector> #include <set> #include <map> #include <queue> #include <string> const int maxn = 100000 + 20; int n; struct node { int L, W, H; node(int LL, int WW, int HH) : L(LL), W(WW), H(HH) {} node() {} bool operator < (const struct node & rhs) const { if (L != rhs.L) return L > rhs.L; else if (W != rhs.W) return W > rhs.W; else return H > rhs.H; } }a[maxn]; int dp[maxn]; bool isok(int one, int two) { if (a[one].L > a[two].L && a[one].W > a[two].W) return true; else return false; } void work () { int t = 0; for (int i = 1; i <= n; ++i) { int x, y, z; cin >> x >> y >> z; a[++t] = node(x, y, z); a[++t] = node(x, z, y); a[++t] = node(y, x, z); a[++t] = node(y, z, x); a[++t] = node(z, x, y); a[++t] = node(z, y, x); } sort(a + 1, a + 1 + t); for (int i = 1; i <= t; ++i) { dp[i] = a[i].H; for (int j = 1; j < i; ++j) { if (isok(j, i)) { dp[i] = max(dp[i], dp[j] + a[i].H); } } } int ans = -inf; for (int i = 1; i <= t; ++i) { ans = max(ans, dp[i]); } static int f = 0; printf("Case %d: maximum height = %d\n", ++f, ans); } int main() { #ifdef local freopen("data.txt","r",stdin); #endif // IOS; while (cin >> n && n) work(); return 0; }
时间: 2024-10-23 16:16:12