poj 1631 最多能有多少条不交叉的线 最大非降子序列 (LIS)
左边的数字是1 2 3 4 5.... 右边的数字 第一个输入的和1连 第2个输入的和2连 右边再按从小到大排序 要求连线不能交叉 问最多能有多少条不交叉的线
假如右边有5个1 那么答案会是5 所以是最大非降子序列
Sample Input
4 //T
6 //n
4
2
6
3
1
5
Sample Output
3
1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <algorithm> 5 # include <cmath> 6 # define LL long long 7 using namespace std ; 8 9 int a[40010] ; 10 int f[40010] ; 11 //int dp[100010] ; 12 int n ; 13 14 int bsearch(int size, const int &a) { 15 int l=0, r=size-1; 16 while( l <= r ){ 17 int mid = (l+r)/2; 18 if( a >= f[mid-1] && a < f[mid] ) return mid;// >&&<= 换为: >= && < 19 else if( a < f[mid] ) r = mid-1; 20 else l = mid+1; 21 } 22 } 23 24 int LIS() 25 { 26 int i, j, size = 1; 27 f[0] = a[0]; 28 // dp[0] = 1; 29 for( i=1; i < n; ++i ) 30 { 31 if( a[i] < f[0] ) j = 0; // <= 换为: < 32 else if( a[i] >= f[size-1] ) j = size++;// > 换为: >= 33 else j = bsearch(size, a[i]); 34 f[j] = a[i]; 35 // dp[i] = j+1; 36 } 37 38 return size; 39 } 40 41 42 int main () 43 { 44 // freopen("in.txt","r",stdin) ; 45 int T ; 46 scanf("%d" , &T) ; 47 while(T--) 48 { 49 int i ; 50 scanf("%d" , &n) ; 51 for (i = 0; i < n ; i++) 52 scanf("%d" , &a[i]) ; 53 printf("%d\n" , LIS()) ; // 求最大递增/上升子序列(如果为最大非降子序列,只需把上面的注释部分给与替换) 54 } 55 56 57 return 0 ; 58 }