题意:
给你n种石头,长x,宽y,高z,每种石头数目无限,一块石头能放到另一块上的条件是:长和宽严格小于下面的石头。问叠起来的最大高度。
思路:
dp[i]表示选择第i个能达到的最大高度。注意每个石头可以有6种组合,都要输入进去。类似于LIS。
#include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; int dp[256]; struct Node { int x, y, z; friend bool operator < (const Node &a, const Node &b) { if (a.x == b.x) return a.y > b.y; return a.x > b.x; } } node[256]; bool judge(const Node &a, const Node &b) { if (a.x < b.x && a.y < b.y) return true; return false; } int main() { int n, count = 0; while (scanf("%d", &n) && n) { for (int i = 0; i < n; ++i) { int a, b, c; scanf("%d %d %d", &a, &b, &c); node[i*6].x = a, node[i*6].y = b, node[i*6].z = c; node[i*6+1].x = a, node[i*6+1].y = c, node[i*6+1].z = b; node[i*6+2].x = b, node[i*6+2].y = a, node[i*6+2].z = c; node[i*6+3].x = b, node[i*6+3].y = c, node[i*6+3].z = a; node[i*6+4].x = c, node[i*6+4].y = a, node[i*6+4].z = b; node[i*6+5].x = c, node[i*6+5].y = b, node[i*6+5].z = a; } sort(node, node + n * 6); int ans = 0; memset(dp, 0, sizeof(dp)); dp[0] = node[0].z; for (int i = 1; i < n * 6; ++i) { dp[i] = node[i].z; for (int j = 0; j < i; ++j) if (judge(node[i], node[j]) && dp[i] < dp[j] + node[i].z) dp[i] = dp[j] + node[i].z; if (dp[i] > ans) ans = dp[i]; } ++count; printf("Case %d: maximum height = %d\n", count, ans); } return 0; }