#include<iostream>
#include<cstring>
using namespace std;
int n; // 矩形个数
bool edges[1001][1001]; // 保存抽象出来的边集合
int arc[1001][2]; // 保存读入的矩形数据
int length[1001]; // 从矩形某一点出发得到的路径长度
int max(int a, int b)
{
if (a > b) return a;
else return b;
}
void init()
{
memset(length, -1, sizeof(length)); // init 初始化函数 把路径和边重新初始化为空
memset(edges, 0, sizeof(edges));
}
int dp(int i)
{
int &ans = length[i]; // 采用刘汝佳的做法,声明一个 length[i]的引用 方便操作
if (ans > 0) // 如果算过了这条边 直接返回这个存好的值
return ans;
ans = 1; // 没算过 假定就这一个点 路径长度为 1
for (int j = 0; j < n; j++)
{
if (edges[i][j])
ans = max(ans, dp(j) + 1); // 状态转移方程 : 返回当前值 和 从该点出发能到达的下一个点 的路径长 + 1
}
return ans; // 记得返回这个值 /(ㄒoㄒ)/~~
}
int main()
{
int T;
cin >> T;
while (T--)
{
cin >> n;
init();
for (int i = 0; i < n; i++)
cin >> arc[i][0] >> arc[i][1];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (arc[i][0] < arc[j][0] && arc[i][1] < arc[j][1])
edges[i][j] = true;
if (arc[i][1] < arc[j][0] && arc[i][0] < arc[j][1])
edges[i][j] = true;
}
}
for (int i = 0; i < n; i++)
dp(i);
int maxLen = -1;
for (int i = 0; i < n; i++)
{
if (length[i] > maxLen)
{
maxLen = length[i];
}
}
cout << maxLen << endl;
}
return 0;
}
2017 - 3 - 27
NOIP 228 天