嵌套矩形问题

来源:互联网 发布:c语言机器人编程代码 编辑:程序博客网 时间:2024/06/03 22:02

描述

有n个矩形,每个矩形可以用a,b来描述,表示长和宽。矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a

输入

第一行是一个正正数N(0

输出

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

样例输入

1101 22 45 86 107 93 15 812 109 72 2

样例输出

5

题目链接

分析

若将每个矩形看作一个点,则整体是一幅DAG(有向无环)图,如果矩形i可以嵌套在矩形j里,则有一条i->j的连线,用g[i][j]=1表示,则问题转化为求DAG上的最长路径,可以用d[i]表示以i为起始点的最长路径,如果由一条i->j的连线,则有

if(g[i][j]==1) //i可以嵌套在j里    d[j] = max(d[j], d[i]+1);

选出数组d中最大的值就是答案

AC代码

#include <bits/stdc++.h>using namespace std;// g[i][j]=1表示矩形i可以放到j里int n, g[1010][1010], d[1010];struct Rec{    int len, width;}rec[1024];//记忆化搜索//如果g[i][j]=1, 表示有一条i, j的路径,//d[j] = max(d[j], d[i+1])int dp(int x){    if(d[x]) return d[x];    int ans = 1;    for(int i=0;i<n;i++){        if(g[i][x])            ans = max(ans, dp(i)+1);    }    d[x] = ans;    return ans;}int main(int argc, char const *argv[]){    // freopen("0", "r", stdin);    int N, a, b, i, j, t;    cin >> N;    while(N--){        cin >> n;        for(i = 0; i<n; i++){            cin >> rec[i].len >> rec[i].width;        }        memset(g, 0, sizeof(g));        memset(d, 0, sizeof(d));        for(i=0;i<n;i++){            for(j=0;j<n;j++){                if(((rec[i].len < rec[j].len) && (rec[i].width < rec[j].width)) ||                   ((rec[i].len < rec[j].width) && (rec[i].width < rec[j].len))){                    g[i][j] = 1;                }            }        }        int ans = 1;        for(i = 0; i<n; i++)            ans = max(ans, dp(i));        cout << ans << endl;    }    return 0;}

扩展

增加打印矩阵序列功能,如果有多组解则使矩形编号的字典序最小.

在上例中10个矩形分别是

1 22 45 86 107 93 15 812 109 72 2

则矩阵嵌套的顺序应该是

7 3 2 1 0

增加打印代码

void print_result(int i){    cout << i << ' ';    for(int j=0;j<n;j++){ //j是从小大到遍历的,因此可以保证字典序最小        if(g[j][i] == 1 && d[j] == d[i]-1){            print_result(j);            break;        }    }}
原创粉丝点击