题目 2075: 矩阵嵌套
时间限制: 1Sec 内存限制: 128MB 提交: 259 解决: 54
题目描述
有 n 个矩形,每个矩形可以用 a,b来描述,表示长和宽。矩形 X(a,b)可以嵌套在矩形 Y(c,d)中当且仅当 a <c,b<d或者 b<c,a<d

(相当于旋转 90 度)。例如(1,5)可以嵌套在(6,2)内,但不能嵌套在(3,4)中。你的任务是选出尽可能多的矩形排成一行,

使得除最后一个外,每一个矩形都可以嵌套在下一个矩形内。
输入
第一行是一个正正数 N(0<N<10),表示测试数据组数。

每组测试数据的第一行是一个正正数 n,表示该组测试数据中含有矩形的个数 (n≤1000)。

随后的 n 行,每行有两个数 a,b(0<a,b≤100),表示矩形的长和宽。

输出
每组测试数据都输出一个数,表示最多符合条件的矩形数目,每组输出占一行。
样例输入
1
10
1 2
2 4
5 8
6 10
7 9
3 1
5 8
12 10
9 7
2 2
样例输出
5

解题思路

矩形之间的嵌套是一个二元关系,由此联系到了邻接矩阵成图的理论,这个图应该是有方向的,因为能否被包含是单方面,故我们根据特性建立一个有向图。由此可得出,我们要求就是这个图(DAG)的最长路径。
状态转移方程: d(i)=max(d(j)+1|(i,j)属于E) 其中E为边的集合
#include <stdio.h> #include <stdlib.h> #define MAX(a,b) ((a)>(b)?(a):(b))
//状态转移方程:d(i)=max(d(j)+1|(i,j)属于E) 其中E为边的集合 int arc[1001][1001]; int d[1001];
//记忆化数组,记得每次使用都要初始化为0 void CreatGraph(int a[],int b[],int n) { int i,j; for(i=0;
i<n;i++) for(j=0;j<n;j++) //双向的故不从i+1开始 { if( (a[i]<a[j]&&b[i]<b[j]) || (b[i]<a[
j]&&a[i]<b[j])) // X(a,b)Y(c,d) a<c,b<d && a<d,b<c arc[i][j]=1; else arc[i][j]=0
; } } int dp(int i,int n) { int j; //int
&ans=d[i];//ans和d[i]共用一个地址即ans与d[i]为一个变量c++用法 int *ans; ans=&d[i];
//用d保存着到以i为起始点的最长路径 if(*ans>0) return *ans; *ans=1; for(j=0;j<n;j++) if(arc[i][j
]) { *ans=MAX(*ans,dp(j,n)+1); //+1代表多一个矩形 } return *ans; } int main() { int T;
scanf("%d",&T); while(T--) { int n,a[1001],b[1001],i,ans=0; scanf("%d",&n); for(
i=0;i<n;i++) d[i]=0; //初始化d for(i=0;i<n;i++) scanf("%d%d",&a[i],&b[i]);
CreatGraph(a,b,n); for(i=0;i<n;i++) ans=MAX(ans,dp(i,n)); //各个点都可能作为起始点 printf(
"%d\n",ans); } return 0; }

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信