题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1475
题意:
对于大小为n的数列,求出最长的Wavio Sequence:1.个数为奇数个 2.左边严格上升的子序列 3.右边严格下降的子序列
思路:
经典的o(nlogn) 的最长上升子序列
重写了严格下降子序列 就是倒着求就行
分别记录左边的上升序列个数和右边下降序列个数,枚举进行比较,找出最大值
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define maxn 10010
#define inf 0x3f3f3f3f
int len;
int a[maxn],b[maxn];
int ASC[maxn],DEC[maxn];
int binary_search(int i){
int L = 1,R = len,mid;
while(L < R){
mid = (L + R) /2;
if(b[mid] >= a[i]) R = mid;
else L = mid + 1;
}
return R;
}
int main()
{
int n;
while(~scanf("%d",&n)){
for(int i = 1 ; i <= n ; i ++){
scanf("%d",&a[i]);
}
memset(b,0,sizeof(b));
memset(ASC,0,sizeof(ASC));
b[1] = a[1];
len = 1;
ASC[1] = 1;
for(int i = 2; i <= n; i ++){
if(a[i] > b[len]){
len ++;
b[len] = a[i];
}
else{
int pos = binary_search(i);
b[pos] = a[i];
}
ASC[i] = len;
}
memset(b,0,sizeof(b));
memset(DEC,0,sizeof(DEC));
b[1] = a[n];
len = 1;
DEC[1] = 1;
for(int i = n - 1; i >= 1; i --){
if(a[i] > b[len]){
len ++;
b[len] = a[i];
}
else{
int pos = binary_search(i);
b[pos] = a[i];
}
DEC[i] = len;
}
int ans = -inf;
for(int i = 1; i <= n ; i ++){
ans = max(ans , min(ASC[i],DEC[i])*2 - 1);
}
printf("%d\n",ans);
}
return 0;
}