PS:求最长上升子序列的n*log(n)的做法:
建一个栈,从前往后遍历数组a[]。
如果栈顶值小于a[i],把a[i]进栈;否则,把栈中第一个大于等于a[i]的数替换为a[i]。
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <string> #include <stack> #include <cmath> #include <queue> #include <set> #include <map> typedef long long ll; using namespace std; const int inf=0x3f3f3f3f; const int maxn=1e4+5; int a[maxn]; int n; int s1[maxn],s2[maxn]; int lis1[maxn],lis2[maxn]; void debug(int de[],int n){ for(int i=0;i<n;++i){ printf("%d ",de[i] ); } printf(" "); } int main() { while(scanf("%d",&n)!=EOF){ memset(lis1,0,sizeof lis1); memset(lis2,0,sizeof lis2); for(int i=0;i<n;++i){ scanf("%d",&a[i]); } int top=-1; for(int i=0;i<n;++i){ if(top==-1){ top++; s1[top]=a[i]; continue; } if(s1[top]<a[i]){ top++; s1[top]=a[i]; }else{ int index=lower_bound(s1,s1+top,a[i])-s1; s1[index]=a[i]; } lis1[i]=top; } //debug(lis1,n); top=-1; for(int i=n-1;i>=0;i--){ if(top==-1){ top++; s2[top]=a[i]; continue; } if(s2[top]<a[i]){ top++; s2[top]=a[i]; }else{ int index=lower_bound(s2,s2+top,a[i])-s2; s2[index]=a[i]; } lis2[i]=top; } //debug(lis2,n); int ans=-1; for(int i=0;i<n;++i){ int tmp=min(lis1[i],lis2[i]); ans=max(tmp,ans); } printf("%d ",2*ans+1 ); } return 0; }