题意:
给一个组数,求递增到递减的最长序列。
e.g 1 2 3 4 5 6 5 4 3 2 1 就是一个长度为11的序列。
解析:
1e4的数据量,nlogn的最长上升子序列的处理方法。
正向扫一遍,找递增,反向扫一遍,找正向递减。
最后比较,mymax = max(mymax, min(cnt1[i], cnt2[i]))。
然后ans = mymax * 2 - 1 就ok啦。
代码:
///nlog(n) lis
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <map>
#define LL long long
using namespace std;
const int maxn = 1e4 + 10;
const int inf = 0x3f3f3f3f;
const double eps = 1e-8;
const double pi = 4 * atan(1.0);
const double ee = exp(1.0);
int a[maxn];
int cnt1[maxn];
int cnt2[maxn];
int tmp[maxn];
int len;
int binarySearch(int key)
{
if (len == 0 || tmp[len] < key)
tmp[++len] = key;
else
{
//debug lower_bound
int lo = 0, hi = len;
while (lo < hi)
{
int mi = (lo + hi) >> 1;
if (key <= tmp[mi])// <= ac ... < wa
hi = mi;
else
lo = mi + 1;
}
///ac
// int lo = lower_bound(tmp, tmp + len, key) - tmp;
tmp[lo] = key;
}
return len;
}
int main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
#endif // LOCAL
int n;
while (scanf("%d", &n) == 1)
{
memset(cnt1, 0, sizeof(cnt1));
memset(cnt2, 0, sizeof(cnt2));
memset(tmp, 0, sizeof(tmp));
len = 0;
for (int i = 0; i < n; i++)
{
scanf("%d", &a[i]);
cnt1[i] = binarySearch(a[i]);
}
len = 0;
memset(tmp, 0, sizeof(tmp));
for (int i = n - 1; i >= 0; i--)
{
cnt2[i] = binarySearch(a[i]);
}
int mymax = 0;
for (int i = 0; i < n; i++)
{
mymax = max(mymax, min(cnt1[i], cnt2[i]));
}
printf("%d\n", mymax * 2 - 1);
}
return 0;
}