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

问题一:

矩形嵌套问题: 给定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\n", 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\n", ++kase, ans);
    }
    return 0;
}

 

posted @ 2015-08-10 14:33  Howe_Young  阅读(371)  评论(0编辑  收藏  举报