POJ 1896

求最长上升与下降序列长度,要用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 }
原文地址:https://www.cnblogs.com/Mr-Xu-JH/p/4004193.html