HDU 1069 Monkey and Banana DP LIS变形题

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
", ++f, ans);
}

int main() {
#ifdef local
    freopen("data.txt","r",stdin);
#endif
//    IOS;
    while (cin >> n && n) work();
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6002368.html