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
" , LIS()) ; // 求最大递增/上升子序列(如果为最大非降子序列,只需把上面的注释部分给与替换)
54     }
55 
56 
57     return 0 ;
58 }
View Code
原文地址:https://www.cnblogs.com/mengchunchen/p/4573586.html