题意:给你一个序列,求一个最长波浪子序列(不一定连续),满足长度为奇数2k+1 它满足前k+1个是严格递增的,后k+1是严格递减的,即相邻两个数不能相同,输出最大长度。
可以转化为经典的LIS问题,预先用O(nlogn)处理出dp1[ i ],dp2[ i ] ,dp1[ i ] 为以第i个数尾的最长递增序列长度,dp2[ i ] 为以i为开头,到n的最长递减序列长度
那么ans = max(ans, 2*min(dp1[i],dp2[i])-1)
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
#define clr(a, x) memset(a, x, sizeof(a))
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define REP(i,a,b) for(int i=a;i<=b;i++)
const int maxn = 10010 ;
int dp1[maxn],dp2[maxn];
int a[maxn];
vector<int>v1,v2;
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
v1.clear(),v2.clear();
for(int i=0;i<n;i++)
{
int t=lower_bound(v1.begin(),v1.end(),a[i])-v1.begin();
if(t==v1.size())
{
v1.push_back(a[i]);
dp1[i]=v1.size();
}
else
{
v1[t]=a[i];
dp1[i]=t+1;
}
t=lower_bound(v2.begin(),v2.end(),a[n-i-1])-v2.begin();
if(t==v2.size())
{
v2.push_back(a[n-i-1]);
dp2[n-i-1]=v2.size();
}
else
{
v2[t]=a[n-i-1];
dp2[n-i-1]=t+1;
}
}
int ans=0;
for(int i=0;i<n;i++)
ans=max(ans,2*min(dp1[i],dp2[i])-1);
printf("%d\n",ans);
}
return 0;
}