• 最长上升子序列(矩形嵌套)


    问题一:

    矩形嵌套问题: 给定n个矩形,每个矩形有个长和宽,只有当一个矩形的长宽小于另外一个矩形的长宽时,才能嵌套在另外一个矩形内部。求出尽量多的矩形排成一行,嵌套的矩形数目最多。

    这个问题其实就是求最长上升子序列,只不过比较大小的时候变成了比较两个变量。

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    #include <algorithm>
    
    using namespace std;
    typedef long long ll;
    const int maxn = 1003;
    struct rect {
        int l, w;
        bool operator < (const rect &b) const {
            return w < b.w && l < b.l;
        }
    };
    bool cmp(const rect &a, const rect &b)
    {
        if (a.l != b.l)
            return a.l < b.l;
        return a.w < b.w;
    }
    rect r[maxn];
    int dp[maxn];
    int main()
    {
        int T, n;
        cin >> T;
        while (T--)
        {
            cin >> n;
            for (int i = 0; i < n; i++)
            {
                cin >> r[i].l >> r[i].w;
                if (r[i].l < r[i].w)
                    swap(r[i].l, r[i].w);
                dp[i] = 1;
            }
            sort(r, r + n, cmp);
            int ans = 1;
            for (int i = 1; i < n; i++)
            {
                for (int j = 0; j < i; j++)
                {
                    if (r[j] < r[i] && dp[i] < dp[j] + 1)
                    {
                        dp[i] = dp[j] + 1;
                    }
                }
                ans = max(ans, dp[i]);
            }
            printf("%d
    ", ans);
        }
        return 0;
    }        
    View Code

    问题二:

    巴比伦塔: 给定n个立方体,求出选一些立方体摞成一个尽量高的柱子,要求每个立方体底面的长宽必须严格小于他下方的立方体的长宽。

    这个问题稍微一转化也是最长上升子序列,只不过是把输入的立方体看成三种立方体就行了。比较大小的时候同样比较的是长和宽。具体代码如下:

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    #include <algorithm>
    
    using namespace std;
    typedef long long ll;
    const int maxn = 100;
    struct rect {
        int l, w, h;
        bool operator < (const rect &b) const {
            return (l < b.l && w < b.w);
        }
        void f(int a, int b, int c)
        {
            l = a; w = b; h = c;
        }
        void exchange()
        {
            if (l < w)
                swap(l, w);
        }
    };
    rect r[maxn];
    int dp[maxn];
    bool cmp(const rect &a, const rect &b)
    {
        if (a.l == b.l)
            return a.w > b.w;
        return a.l > b.l;
    }
    int main()
    {
        int n, kase = 0;
        while (~scanf("%d", &n) && n)
        {
            int a, b, c, cnt = 0;
            rect tmp;
            for (int i = 0; i < n; i++)
            {
                scanf("%d %d %d", &a, &b, &c);//将这个立方体分别转化成三个立方体,高度分别为a, b, c
                tmp.f(a, b, c); tmp.exchange(); r[cnt++] = tmp;
                tmp.f(a, c, b); tmp.exchange(); r[cnt++] = tmp;
                tmp.f(b, c, a); tmp.exchange(); r[cnt++] = tmp;
            }
            sort(r, r + cnt, cmp);
            memset(dp, 0, sizeof(dp));
            int ans = 0;
            for (int i = 0; i < cnt; i++)//最长子序列
            {
                dp[i] = r[i].h;
                for (int j = 0; j < i; j++)
                {
                    if (r[i] < r[j])
                        dp[i] = max(dp[i], dp[j] + r[i].h);
                }
                ans = max(ans, dp[i]);
            }
            printf("Case %d: maximum height = %d
    ", ++kase, ans);
        }
        return 0;
    }
  • 相关阅读:
    day07_final
    day06_final
    day02_final
    day04_final
    New
    AtCoder Grand Contest 015 E Mr.Aoki Incubator
    长链剖分学习笔记
    关于某些莫队的优化
    CodePlus 2019 3月月赛 Div.1 A题 TREE
    边分治学习笔记
  • 原文地址:https://www.cnblogs.com/Howe-Young/p/4717953.html
Copyright © 2020-2023  润新知