用树状数组优化DP。。。。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define lowbit(x) (x&(-x))
const int maxn = 1005;
int tree[maxn][maxn];
pair<int, int> a[maxn];
int t[maxn], y[maxn], n, cnt;
int cmp(pair<int, int> aa, pair<int, int> bb)
{
if(aa.first != bb.first) return aa.first > bb.first;
return aa.second < bb.second;
}
void add(int x, int y, int v)
{
for(; y <= cnt; y += lowbit(y)) tree[x][y] = max(tree[x][y], v);
}
int query(int x, int y)
{
int res = 0;
for(; y; y -= lowbit(y)) res = max(res, tree[x][y]);
return res;
}
void work()
{
cnt = 0;
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%d%d", &a[i].first, &a[i].second);
y[cnt++] = a[i].second;
}
sort(y, y+cnt);
cnt = unique(y, y+cnt) - y;
for(int i = 1; i <= n; i++) a[i].second = lower_bound(y, y+cnt, a[i].second) - y + 1;
memset(tree, 0, sizeof tree);
sort(a+1, a+n+1, cmp);
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= cnt; j++) t[j] = query(j, a[i].second) + 1;
for(int j = 1; j <= cnt; j++) {
add(j, a[i].second, t[j]);
add(a[i].second, j, t[j]);
}
}
int ans = 0;
for(int i = 1; i <= cnt; i++) ans = max(ans, query(i, cnt));
printf("%d\n", ans);
}
int main()
{
int _;
scanf("%d", &_);
while(_--) work();
return 0;
}