L i n k Link Link
D e s c r i p t i o n Description Description
S a m p l e Sample Sample I n p u t Input Input
8
1 9 2 6 8 1 7 1926817
S a m p l e Sample Sample O u t p u t Output Output
5
H i n t Hint Hint
S o l u t i o n Solution Solution
首先把加进队列的数分成两份,左边求一个最大上升序列,右边也是如此,将阻挡形成上升序列的数字删去,最后还原回原序列中,就会发现是求一个最长下降子序列 + 最长上升序列(删去一些数后),最后会有一个重复的,减去即可
C o d e Code Code
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n, ans;
int a[100001], b[100001], c[100001], ans1[100001], ans2[100001];
int main()
{
scanf("%d", &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)
{
int now = lower_bound(c + 1, c + c[0] + 1, b[i]) - c;
c[now] = b[i];
if (now > c[0]) c[0]++;
ans1[n - i + 1] = now;
}//求最长上升子序列
for (int i = 1; i <= n; ++i)
b[i] = -a[n - i + 1];
memset(c, 0, sizeof(c));
for (int i = 1; i <= n; ++i)
{
int now = lower_bound(c + 1, c + c[0] + 1, b[i]) - c;
c[now] = b[i];
if (now > c[0]) c[0]++;
ans2[n - i + 1] = now;
}//求最长下降子序列
for (int i = 1; i <= n; ++i)
ans = max(ans1[i] + ans2[i] - 1, ans);//找出最大的
printf("%d", ans);
return 0;
}