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("\n");
}
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\n",2*ans+1 );
}
return 0;
}