HDU

HDU

input:

1
10 20 30
2
6 8 10
5 5 5
7
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
5
31 41 59
26 53 58
97 93 23
84 62 64
33 83 27
0

output:

Case 1: maximum height = 40
Case 2: maximum height = 21
Case 3: maximum height = 28
Case 4: maximum height = 342

 题目大意:

有n种方块(x,y,z三个属性),每种可以用无数次。要求上方的方块底面边长要都小于下面方块底面的边长,求用
这n块方块最多能搭多高。

 分析:

最长上升子序列。一块方块有6种摆法,所以事先将6种摆法放入数组,并按照底面边长从小到大排序。dp[j]=前i
个最顶上为j方块的高度。

 code:

#define frp

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
const ll INF = 0x3f3f3f3f;
const ll inf = 0x7fffff;
const int maxn = 1e8;
const int MAXN = 10000;
int n;

struct node {
    int x, y, z;

    bool operator<(const node &a) const {
        return x == a.x ? y < a.y : x < a.x;
    }
} block[MAXN];

int dp[MAXN];


void solve() {
    int t = 1;
    while (cin >> n && n) {
        int cnt = 0;
        int x, y, z;
        for (int i = 0; i < n; i++) {
            cin >> x >> y >> z;
            block[cnt++] = {x, y, z};
            block[cnt++] = {x, z, y};
            block[cnt++] = {y, x, z};
            block[cnt++] = {y, z, x};
            block[cnt++] = {z, x, y};
            block[cnt++] = {z, y, x};
        }
        int ans = 0;
        sort(block, block + cnt);
        for (int i = 0; i < cnt; i++) {
            dp[i] = block[i].z;
            for (int j = 0; j < i; j++) {
                if (block[j].x < block[i].x && block[j].y < block[i].y) {
                    dp[i] = max(dp[j] + block[i].z, dp[i]);
                }
            }
            ans = max(ans, dp[i]);
        }
        cout << "Case " << t++ << ": maximum height = " << ans << endl;
    }
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
#ifdef frp
    freopen("D:\coding\c_coding\in.txt", "r", stdin);
//    freopen("D:\coding\c_coding\out.txt", "w", stdout);
#endif
    solve();
    return 0;
}