1. 程式人生 > 實用技巧 >最長上升子序列加強版

最長上升子序列加強版

描述

給出N個數,它們各不相同,求最長上升子序列

輸入

先給出一個數字N,代表有N組資料
對於每組資料,先給出一個數字TOT,TOT小於等於40000.
接下來有TOT個數字,為1到40000的某個排列.

輸出

針對每組資料,輸出最長上升序列的長度

樣例

輸入

4
6
4
2
6
3
1
5
10
2
3
4
5
6
7
8
9
10
1
8
8
7
6
5
4
3
2
1
9
5
8
9
2
3
1
7
4
6

輸出

3
9
1
4
 1 #include<bits/stdc++.h>
 2 #define lowbit(x) x&(-x)
 3 using
namespace std; 4 int n,t,a[400001],sum[400001],f[400001]; 5 void add(int x,int val) { 6 while(x<=n) { 7 sum[x]=max(sum[x],val); 8 x+=lowbit(x); 9 } 10 } 11 int ask(int x) { 12 int ans=INT_MIN; 13 while(x) { 14 ans=max(sum[x],ans); 15 x-=lowbit(x); 16 }
17 return ans; 18 } 19 int main() { 20 scanf("%d",&t); 21 while(t--) { 22 int ans=INT_MIN; 23 memset(sum,0,sizeof(sum)); 24 memset(f,0,sizeof(f)); 25 scanf("%d",&n); 26 for(int i=1; i<=n; i++) 27 scanf("%d",&a[i]); 28 for
(int i=1; i<=n; i++) { 29 int num=-1; 30 num=max(ask(a[i]),num); 31 f[i]=num+1; 32 add(a[i],f[i]); 33 } 34 for(int i=1; i<=n; i++) 35 ans=max(ans,f[i]); 36 printf("%d\n",ans); 37 } 38 return 0; 39 }