题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4604
思路:就是模拟一下,求每一个开始的非上升和非下降序列。然后求重复的数,由于求出来可能不会是我们想要的序列如22221122233
这样的话求出来的会是2222222 222222233,而我们想要的到的是112222,所以不能用普通的,而是用N*logN(当然也是因为数列太长),而我们得到的是1122222多处一个2这个2是11之前留下的,但是因为2比1大才留下,那么2一定会留在最长上升里面,所以2是会被算作重复的减掉。
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <algorithm> 5 #include <cstring> 6 #include <map> 7 #define MAXN 100010 8 #define INF 1000000007 9 #define FI first 10 #define SE second 11 using namespace std; 12 int a[MAXN],f1[MAXN],f2[MAXN],d[MAXN]; 13 int bs(int key,int len) 14 { 15 int l,r; 16 l = 1,r = len; 17 while(l <= r) 18 { 19 int mid = (l+r)>>1; 20 if(key >= f1[mid-1] && key < f1[mid]) { 21 //puts("yes"); 22 return mid; 23 } 24 else if(key < f1[mid]) r = mid-1; 25 else 26 l = mid+1; 27 } 28 } 29 int bx(int key,int len) 30 { 31 int l,r; 32 l = 1,r = len; 33 while(l <= r) 34 { 35 int mid = (l+r)>>1; 36 if(key <= f2[mid-1] && key > f2[mid]) return mid; 37 else if(key > f2[mid]) r = mid-1; 38 else 39 l = mid+1; 40 } 41 } 42 int searchlap(int b[],int val,int len,int s,int t) 43 { 44 int l,r,mid; 45 l = s,r = t; 46 mid = (l+r)/2; 47 if(b[l] == val && b[r] == val) return r-l+1; 48 else if(l >= r) return 0; 49 else if(b[mid] == val) return 1+searchlap(b,val,len,l,mid-1)+searchlap(b,val,len,mid+1,r); 50 else if(b[mid] > val) return searchlap(b,val,len,l,mid-1); 51 else if(b[mid] < val) return searchlap(b,val,len,mid+1,r); 52 } 53 int searchlap1(int b[],int val,int len,int s,int t) 54 { 55 int l,r,mid; 56 l = s,r = t; 57 mid = (l+r)/2; 58 if(b[l] == val && b[r] == val) return r-l+1; 59 else if(l >= r) return 0; 60 else if(b[mid] == val) return 1+searchlap1(b,val,len,l,mid-1)+searchlap1(b,val,len,mid+1,r); 61 else if(val > b[mid]) return searchlap1(b,val,len,l,mid-1); 62 else if (b[mid] > val)return searchlap1(b,val,len,mid+1,r); 63 } 64 int main() 65 { 66 int ncase,n,ans,i,j; 67 //freopen("text.txt","r",stdin); 68 scanf("%d",&ncase); 69 while(ncase--) 70 { 71 ans=0; 72 scanf("%d",&n); 73 int len1,len2; 74 for( i=0;i<n;++i) scanf("%d",&a[i]); 75 f1[0] = -1000000; 76 f2[0] = 1000000; 77 len1 = len2 = 0; 78 int nowl1,nowl2; 79 int cnt = 0; 80 int lap1,lap2; 81 for(i = n-1;i >= 0;i--) 82 { 83 cnt++; 84 int k; 85 if(a[i] < f1[0]) j = 0; 86 else if(a[i] >= f1[len1]) len1++,j = len1; 87 else 88 { 89 j = bs(a[i],len1); 90 } 91 f1[j] = a[i]; 92 lap1 = searchlap(f1,a[i],len1,1,len1); 93 nowl1 = j; 94 if(a[i] > f2[0]) j = 0; 95 else if(a[i] <= f2[len2]) len2++,j=len2; 96 else 97 { 98 j = bx(a[i],len2); 99 } 100 f2[j] = a[i]; 101 lap2 = searchlap1(f2,a[i],len2,1,len2); 102 nowl2 = j; 103 ans = max(ans,nowl1+nowl2-min(lap1,lap2)); 104 } 105 cout<<ans<<endl; 106 } 107 return 0; 108 }