分析:有n (n≤30) 种立方体,每种都有无穷多个。要求选一些立方体摞成一根尽量高的柱子(可以自行选择哪一条边作为高),使得每个立方体的底面长款分别严格小于它下方立方体的底面长宽。(本段摘自《算法竞赛入门经典(第2版)》)
分析:
DAG上的动态规划。直接套用DAG最长路算法。
代码:
#include <iostream>
#include <algorithm>
#include <fstream>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <cmath>
#include <cctype>
#include <stack>
#include <set>
using namespace std;
const int maxn = 30 + 5, INF = 1000000000;
struct Node
{
int x[3];
};
int n, C, ans;
Node a[maxn];
int d[maxn][3];
int dp(int i, int j)
{
int& ans = d[i][j];
if (ans > 0)
return ans;
ans = a[i].x[j];
for (int k = 0; k < n; ++k)
for (int l = 0; l < 3; ++l)
if (max(a[k].x[(l + 1) % 3], a[k].x[(l + 2) % 3]) < max(a[i].x[(j + 1) % 3], a[i].x[(j + 2) % 3]) && min(a[k].x[(l + 1) % 3], a[k].x[(l + 2) % 3]) < min(a[i].x[(j + 1) % 3], a[i].x[(j + 2) % 3]))
ans = max(ans, dp(k, l) + a[i].x[j]);
return ans;
}
int main()
{
while (~scanf("%d", &n), n)
{
ans = 0;
memset(d, 0, sizeof(d));
for (int i = 0; i < n; ++i)
scanf("%d%d%d", &a[i].x[0], &a[i].x[1], &a[i].x[2]);
for (int i = 0; i < n; ++i)
for (int j = 0; j < 3; ++j)
ans = max(ans, dp(i, j));
printf("Case %d: maximum height = %d\n", ++C, ans);
}
return 0;
}