题目 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;
}
版权声明:本文为m0_52103105原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。