简单dp
//这道题目就是小白书上的矩形嵌套
//开始时没有用记忆化搜索直接写了递归的
//转移方程结果超时了
#include<iostream>
#include<cstring>
using namespace std;
int G[1010][1010];
int d[1010]; //用于记忆已经求出的顶点状最长路径长度
int dp(int i,int n) //返回从i出发的最大路径长度
{
int& ans=d[i]; //声明ans为d[i]的引用
if(ans>0) return ans; //d[i]已经计算出来了,直接返回
ans=1;
for(int j=1;j<=n;j++)
if(G[i][j])
ans=ans>dp(j,n)+1?ans:dp(j,n)+1;
return ans;
}
typedef struct //表示矩形的结构体
{
int x;
int y;
}R;
inline int swap(int &a,int &b)
{
int t;
if(a>b)
{
t=b;
b=a;
a=t;
}
}
int main()
{
int i,j,t,n,a,b,max;
R r[1100];
cin>>t;
while(t--)
{
cin>>n;
for(i=1;i<=n;i++) //矩形编号1--n
{
cin>>a>>b;
if(a>b)
swap(a,b); //保证宽比长小
r[i].x=a;r[i].y=b;
}
memset(G,0,sizeof(G)); //初始化图的邻接矩阵
memset(d,0,sizeof(d));
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(r[i].x<r[j].x&&r[i].y<r[j].y)
G[i][j]=1; //矩形i可嵌套到j中,在途中添加一条边
max=0;
for(i=1;i<=n;i++)
if(max<dp(i,n)) //对每个顶点找一次最长路径并求其中的最大值、
max=dp(i,n);
cout<<max<<endl;
}
return 0;
}