前后都来一遍最长上升子序列。注意要用nlogn复杂度的算法
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int maxn = 10000 + 5;
const int INF = ~0U >> 1;
int a[maxn], dp1[maxn], dp2[maxn];
int d[maxn];
int n;
int main() {
while(scanf("%d", &n) != EOF) {
memset(dp1, 0, sizeof(dp1));
memset(dp2, 0, sizeof(dp2));
for(int i = 0; i < n; ++i) {
scanf("%d", &a[i]);
d[i] = INF;
}
d[n] = INF;
d[0] = 0;
int len = 0, x;
for(int i = 0; i < n; ++i) {
if(a[i] > d[len]) x = ++len;
else x = lower_bound(d, d + n, a[i]) - d;
d[x] = a[i];
dp1[i] = x;
}
for(int i = 0; i <= n; ++i) d[i] = INF;
d[0] = 0;
reverse(a, a + n);
len = 0;
for(int i = 0; i < n; ++i) {
if(a[i] > d[len]) x = ++len;
else x = lower_bound(d, d + n, a[i]) - d;
d[x] = a[i];
dp2[i] = x;
}
int ans = -INF;
for(int i = 0; i < n; ++i) {
int f = min(dp1[i], dp2[n-i-1]) * 2 - 1;
ans = max(f, ans);
}
printf("%d\n", ans);
}
return 0;
}