求最长上升与下降序列长度,要用nlogn的算法 用n^2的算法会超时
1 #include <iostream> 2 #include <cstdio> 3 #include <string.h> 4 using namespace std; 5 double h[1002],b[1002]; 6 int n; 7 int find1(double *a,int l,int r,double k){//最长上升子序列 参考nlogn 8 while(l<=r){ 9 int mid=(l+r)/2; 10 if(k>a[mid])l=mid+1; 11 else if(k<a[mid])r=mid-1; 12 else return mid; 13 } 14 return l; 15 } 16 int find2(double *a,int l,int r,double k){ //最长下降子序列 中的二分查找 17 while(l<=r){ 18 int mid=(l+r)/2; 19 if(k>a[mid])r=mid-1; 20 else if(k<a[mid])l=mid+1; 21 else return mid; 22 } 23 return l; 24 } 25 int lis(int k){ 26 memset(b,0,sizeof(b)); 27 int maxl=1,maxr=1; 28 b[0]=-1; 29 b[1]=h[1]; 30 int j; 31 for(int i=2;i<=k;i++){ 32 j=find1(b,1,maxl,h[i]); 33 b[j]=h[i]; 34 if(j>maxl)maxl=j; 35 } 36 b[1]=h[k+1]; 37 for(int i=k+2;i<=n;i++){ 38 j=find2(b,1,maxr,h[i]); 39 b[j]=h[i]; 40 if(j>maxr)maxr=j; 41 } 42 return n-maxl-maxr; 43 } 44 int main(){ 45 scanf("%d",&n); 46 for(int i=1;i<=n;i++)scanf("%lf",h+i); 47 int minp=10000; 48 for(int i=1;i<=n;i++){ 49 int l=lis(i); 50 minp=min(minp,l); 51 } 52 printf("%d ",minp); 53 return 0; 54 }