1 5 1 1 2 3 3 2 4 3 5 1
4
对d进行离散化。用dp[i][j]表示取到当前位置,两个子序列的最后一个苹果的可口值是i和j的情况下,
最多能吃的苹果个数。
对于当前的d,枚举i进行转移公式:dp[i][d] = dp[d][i] = dp[i][j] + 1 (j <= d)
根据不降子序列的性质有单调性,只需dp[i][d] = dp[d][i] = max(dp[i][j]), j<=d
用树状数组维护最大值即可
#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #include<vector> using namespace std; #define maxn 1001 int tree[maxn][maxn]; int m; void add(int *T,int p,int n){ for(;p<=m;p+=p&-p) T[p] = max(T[p],n); } int query(int *T,int p){ int ans = 0; for(;p>0;p-=p&-p) ans = max(ans,T[p]); return ans; } struct Node{ int h,d; }; Node p[1001]; int comp(Node a,Node b){ if(a.h == b.h) return a.d > b.d; return a.h < b.h; } int haha[maxn]; int main(){ int t,n,h,d; //freopen("1001.in","r",stdin); //freopen("1001x.out","w",stdout); scanf("%d",&t); while(t--) memset(tree,0,sizeof(tree)); scanf("%d",&n); for(int i = 0 ;i < n; i++){ scanf("%d%d",&p[i].h,&p[i].d); haha[i] = p[i].d; } sort(haha,haha+n); m = unique(haha,haha+n)-haha; sort(p,p+n,comp); for(int i = 0;i < n; i++) p[i].d = m-(lower_bound(haha,haha+m,p[i].d)-haha); int d,u,v; for(int i = 0;i < n; i++){ memset(haha,0,sizeof(haha)); d = p[i].d; for(int j = 1;j <= m; j++) haha[j] = query(tree[j],d)+1; for(int j = 1;j <= m; j++){ add(tree[j],d,haha[j]); add(tree[d],j,haha[j]); } } int ans = 0; for(int i = 1;i <= m; i++) ans = max(ans,query(tree[i],m)); printf("%d\n",ans); } return 0; }