• HDU


    Monkey and Banana

    题目大意:

    给你n种长方体,每种立方体都有个长宽高,每种立方体有无数个,让你选择任意立方体堆起来,要求上面的长和宽都严格小于下面的长和宽,问你最高能堆多高。

    数据范围:

    0<n30,多组输入到n为0时结束输入。

    解题思路:

    每种立方体又可分为三种立方体,即一共有3n个立方体,而每个立方体由于不可能使得底面相同,所以最多只能选一个,这时就可以确定一个状态,dp[i]代表以第i个立方体为底时可得的最大高度,即第i个状态可从前i-1个状态转移过来,即

    for(int j = 1; j < i; j++) {
        if(ans[i].a > ans[j].a && ans[i].b > ans[j].b) {
            dp[i] = max(dp[i], dp[j] + ans[j].c);//(其中ans[j].c为第j个块的高度)
        }
    }

    但是这样的话,如果大的底在前面的话就不能保证答案的正确,可以将数组重复3n次,那么每个数都能跑到,但是这样就导致复杂度接受不了,单n等于30是就接近1e8了,还是多组,果断TLE了,所以,可以对底边从小到大排序一下,保证小底在前,就能AC了。(仔细想想,确定了宽是从小到大,宽相同时长按小到大,是能保证答案正确的,因为假如当前立方体宽较小而长较长,那么即使将它的被访问顺序往后挪的话,那么即使长度能满足了,那么宽度便满足不了了)

    AC代码

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int maxn = 10000;
    typedef long long LL;
    LL dp[maxn + 5];
    int n, tot;
    struct NOOD {
        LL a, b, c;
    }ans[maxn+ 5];
    bool cmp(NOOD x, NOOD y) {
        if(x.a == y.a)return x.b < y.b;
        return x.a < y.a;
    }
    int main() {
        while(~scanf("%d", &n) && n) {
            int t = 0;
            LL Maxm = 0;
            memset(dp, -1, sizeof(dp));
            for(int i = 1; i <= n; i++) {
                LL x, y, z;
                scanf("%lld%lld%lld", &x, &y, &z);
                ans[++t].a = x, ans[t].b = y, ans[t].c = z;
                ans[++t].a = z, ans[t].b = x, ans[t].c = y;
                ans[++t].a = y, ans[t].b = z, ans[t].c = x;
            }
            for(int i = 1; i <= t; i++) if(ans[i].a > ans[i].b)swap(ans[i].a, ans[i].b);
            sort(ans + 1, ans + t + 1, cmp);
            dp[1] = ans[1].c;
            Maxm = dp[1];
            for(int i = 2; i <= t; i++) {
                dp[i] = ans[i].c;
                for(int j = 1; j < i; j++) {
                    if(ans[i].a > ans[j].a && ans[i].b > ans[j].b) {
                        dp[i] = max(dp[i], dp[j] + ans[i].c);
                    }
                }
                Maxm = max(Maxm, dp[i]);
            }
            printf("Case %d: maximum height = %lld
    ", ++tot, Maxm);
        }
        return 0;
    }
  • 相关阅读:
    class 类添加属性
    Ajax请求数据data被JSON.stringify()的数据django解码过程
    Python之浏览器的前进或后退
    滚动条-智能等待-富文本
    Python之阶乘代码
    Python之用型号构成一个三角形代码
    C# Dictionary
    使用C#创建Windows服务
    sql取出每月最早的上报的数据
    mvc NPOI导入读取Excel文件
  • 原文地址:https://www.cnblogs.com/TRDD/p/9813535.html
Copyright © 2020-2023  润新知