题目链接
题目大意:找一个最长(假设长度为2N-1)的子序列,使得前N个元素递增,后N个元素递减。
解题报告:LIS
nlogn求LIS链接
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 1e4 + 7;
int A[maxn], B[maxn], du[maxn], dd[maxn];
int an1[maxn], an2[maxn];
int main(){
int n;
while( scanf("%d", &n )==1 && n ){
for ( int i=1; i<=n; i++ ) scanf("%d", &A[i] ), B[n-i+1]=A[i];
//for ( int i=1; i<=n; i++ ) printf("%d", B[i] );
int len1=1, len2=1;
an1[1]=A[1], an2[1]=B[1];
dd[1]=du[1]=1;
for ( int i=2; i<=n; i++ ){
if( A[i]>an1[len1] ) an1[++len1]=A[i];
else {
int t=lower_bound(an1+1,an1+len1,A[i])-an1;
an1[t]=A[i];
}
du[i]=len1;
if( B[i]>an2[len2] ) an2[++len2]=B[i];
else {
int t=lower_bound(an2+1,an2+len2,B[i])-an2;
an2[t]=B[i];
}
dd[i]=len2;
}
// for ( int i=1; i<=n; i++ ) printf("%d ", du[i] );
// printf("\n");
// for ( int i=1; i<=n; i++ ) printf("%d ", dd[i] );
int ans=0;
for ( int i=1; i<=n; i++ )
ans=max(ans, min(du[i], dd[n-i+1]) );
printf("%d\n", ans*2-1);
}
}