hdu 1069(记忆化搜索/LIS)

来源:互联网 发布:win7做mac启动盘 编辑:程序博客网 时间:2024/06/05 19:02

题意: 给你n种立方体的长宽高,每种都有无限个,立方体可以旋转。现在要摞立方体使得摞起来的高度尽可能高,要求上面的立方体的长和宽必须严格小于下面的立方体。

思路:每种立方体都有三种摆法,长宽高:(a, b, c)(a, c, b) (b, c, a)  输入的时候处理一下,存n*3个立方体。可以排一下序LIS来做,也可以记忆化搜索。

我写的记忆化搜索,但是一直WA,后来改成了LIS,可还是WA,看了半天也没看出有什么bug,于是去看了别人写的,发现跟我写的本质上没什么区别。。。。。。

最后发现不是我写错了,而是。。。用G++交可以过,之前一直用C++交就会WA,WTF,什么鬼。。。


记忆化搜索:

# include <iostream># include <algorithm># include <cstdio># include <cstring>using namespace std;typedef long long ll;const int maxn = 100 + 5;int dp[maxn];int G[maxn][maxn];int n;struct Node {    int a, b, c;    void Set(int aa, int bb, int cc) {        a = aa; b = bb; c = cc;    }} res[maxn];int dfs(int);void init();int main(void){    int Case = 0;    while (scanf("%d", &n) && n) {        init();        int ans = 0;        for (int i = 0; i < n; ++i) ans = max(ans, dfs(i));        printf("Case %d: maximum height = %d\n", ++Case, ans);    }    return 0;}int dfs(int id) {    int& d = dp[id];    if (d != -1) return d;    d = res[id].c;    for (int i = 0; i < n; ++i) {        if (G[id][i]) d = max(d, dfs(i) + res[id].c);    }    return d;}void init() {    memset(dp, -1, sizeof dp);    memset(G, 0, sizeof G);    int t = 0; n *= 3;    while (t < n) {        scanf("%d %d %d", &res[t].a, &res[t].b, &res[t].c); ++t;        res[t++].Set(res[t - 1].a, res[t - 1].c, res[t - 1].b);        res[t++].Set(res[t - 1].b, res[t - 1].c, res[t - 1].a);    }    for (int i = 0; i < n; ++i) {        if (res[i].a < res[i].b) swap(res[i].a, res[i].b);    }    for (int i = 0; i < n; ++i) {        for (int j = 0; j < n; ++j) {            if (res[i].a < res[j].a && res[i].b < res[j].b)                G[i][j] = 1;        }    }}

LIS:

# include <iostream># include <algorithm># include <cstdio># include <cstring>using namespace std;typedef long long ll;const int maxn = 100 + 5;int dp[maxn];int n;struct Node {    int a, b, c;    bool operator < (const Node& n) const {        if (a == n.a) return b > n.b;        return a > n.a;    }    void Set(int aa, int bb, int cc) {        a = aa; b = bb; c = cc;    }} res[maxn];int main(void){    int Case = 0;    while (scanf("%d", &n) && n) {        int t = 0; n *= 3;        while (t < n) {            scanf("%d %d %d", &res[t].a, &res[t].b, &res[t].c); ++t;            res[t++].Set(res[t - 1].a, res[t - 1].c, res[t - 1].b);            res[t++].Set(res[t - 1].b, res[t - 1].c, res[t - 1].a);        }        for (int i = 0; i < n; ++i) {            if (res[i].a < res[i].b) swap(res[i].a, res[i].b);        }        sort(res, res + n);        for (int i = 0; i < n; ++i) dp[i] = res[i].c;        for (int i = 0; i < n; ++i) {            for (int j = 0; j < i; ++j) {                if (res[i].a < res[j].a && res[i].b < res[j].b)                    dp[i] = max(dp[i], dp[j] + res[i].c);            }        }        int ans = 0;        for (int i = 0; i < n; ++i) ans = max(ans, dp[i]);        printf("Case %d: maximum height = %d\n", ++Case, ans);    }    return 0;}


0 0