矩形嵌套(DAG最长路)

Description

有n个矩形,每个矩形可以用a,b来描述,表示长和宽。矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a<c,b<d或者b<c,a<d(相当于旋转X90度)。例如(1,5)可以嵌套在(6,2)内,但不能嵌套在(3,4)中。你的任务是选出尽可能多的矩形排成一行,使得除最后一个外,每一个矩形都可以嵌套在下一个矩形内。

Input

第一行是一个正正数N(0<N<10),表示测试数据组数,
每组测试数据的第一行是一个正正数n,表示该组测试数据中含有矩形的个数(n<=1000)
随后的n行,每行有两个数a,b(0<a,b<100),表示矩形的长和宽

Output

每组测试数据都输出一个数,表示最多符合条件的矩形数目,每组输出占一行

Sample Input Copy

1
10
1 2
2 4
5 8
6 10
7 9
3 1
5 8
12 10
9 7
2 2 

Sample Output Copy

5

思路

对于任意两个矩形A,B如果A嵌套在B内,那么B一定不会嵌套在A内,所以如果将一个个矩形视为节点的话,那么矩形间的嵌套关系可以用一张有向无环图表示,故此题可以抽象成一个DAG最长路问题,数组dp[]的第 i 个元素dp[i]表示从第 i 个矩形开始所能嵌套的最多的矩形个数,故可以写出如下状态转移方程:dp[i] = max(dp[i], dp[j] + 1)

代码(C++)

#include <iostream>
#include <cmath>
#include <cstring>
#define MAXN 1005
using namespace std;
struct rect{
    int l, w;
}rects[MAXN];
int dp[MAXN], n, T, res;
int DP(int i){
    if(dp[i] > 0)return dp[i];
    for(int j = 0; j < n; j++){
        if((rects[i].l < rects[j].l && rects[i].w < rects[j].w) || (rects[i].l < rects[j].w && rects[i].w < rects[j].l)){
            dp[i] = max(dp[i], DP(j) + 1);
            if(dp[i] > res)res = dp[i];
        }
    }
    return dp[i];
}
int main(){
    scanf("%d", &T);
    while(T--){
        memset(dp, 0, sizeof(dp));
        res = 0;
        scanf("%d", &n);
        for(int i = 0; i < n; i++){
            scanf("%d%d", &rects[i].l, &rects[i].w);
        }
        DP(0);
        printf("%d\n", res + 1);
    }
    return 0;
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 矩阵嵌套描述有n个矩形,每个矩形可以用a,b来描述,表示长和宽。矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅...
    laochonger阅读 1,469评论 0 0
  • 时间限制: 1Sec 内存限制: 128MB 提交: 109 解决: 14 题目描述有 n 个矩形,每个矩形可以用...
    桐桑入梦阅读 539评论 0 0
  • 学会使用CSS选择器熟记CSS样式和外观属性熟练掌握CSS各种选择器熟练掌握CSS各种选择器熟练掌握CSS三种显示...
    七彩小鹿阅读 6,342评论 2 66
  • 标签(空格分隔): 算法 C++ 笔试 第三题:描述小王最近在开发一种新的游戏引擎,但是最近遇到了性能瓶颈。于是他...
    认真学计算机阅读 1,939评论 0 8
  • 给一个直方图,求直方图中的最大矩形的面积。例如,下面这个图片中直方图的高度从左到右分别是2, 1, 4, 5, 1...
    Picksy阅读 166评论 0 0