自己还是太水。。。光理解题。就理解了好久。。。
每种箱子。可以有N种。而每个箱子有3个面。
而没两个面都可以做为底面。
所以每个箱子有6种情况。。。
将所有情况按地面的长 和 宽 排序。长若相等,则按宽排。
接下来就是求最长下降子序列的过程求 最高的 楼梯。。。
#include <cstdio>
#include <algorithm>
#include <cstring>
const int MAX = 35;
using namespace std;
struct DP {
int x, y, z;
}dp[MAX * 6];
bool cmp ( DP a, DP b ) {
if ( a.x == b.x ) return a.y > b.y;
else return a.x > b.x;
}
int main ( ) {
int n, i, j, k, a, b, c, Case = 1, opt[MAX * 6];
while ( scanf ( "%d", &n ) != EOF && n ) {
memset ( opt, 0, sizeof ( opt ) );
for ( k = i = 0; i < n; ++i ) {
scanf ( "%d%d%d", &a, &b, &c );
dp[k].x = a, dp[k].y = b, dp[k].z = c, ++k;
dp[k].x = a, dp[k].y = c, dp[k].z = b, ++k;
dp[k].x = b, dp[k].y = a, dp[k].z = c, ++k;
dp[k].x = b, dp[k].y = c, dp[k].z = a, ++k;
dp[k].x = c, dp[k].y = a, dp[k].z = b, ++k;
dp[k].x = c, dp[k].y = b, dp[k].z = a, ++k;
}
sort ( dp, dp + k, cmp );
opt[0] = dp[0].z;
for ( i = 1; i < k; ++i ) {
int Max = 0;
for ( j = i - 1; j >= 0; --j )
if ( dp[i].x < dp[j].x && dp[i].y < dp[j].y && opt[j] > Max ) Max = opt[j];
opt[i] = Max + dp[i].z;
}
int Max = 0;
for ( i = 0; i < k; ++i )
if ( opt[i] > Max ) Max = opt[i];
printf ( "Case %d: maximum height = %d\n", Case++, Max );
}
}