用树状数组优化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; }