您的位置:首页 > 其它

A序列(最长上升子序列)

2017-08-15 15:20 183 查看


A序列

发布时间: 2017年7月9日 18:17   最后更新: 2017年7月9日 21:05   时间限制: 1000ms   内存限制: 128M

描述

如果一个序列有奇数个正整数组成,不妨令此序列为a1,a2,a3,...,a2∗k+1(0<=k),并且a1,a2...ak+1是一个严格递增的序列,ak+1,ak+2,...,a2∗k+1,是一个严格递减的序列,则称此序列是A序列。
比如1 2 5 4 3就是一个A序列。
现在Jazz有一个长度为n的数组,他希望让你求出这个数组所有满足A序列定义的子序列里面最大的那个长度。(子序列可以不连续)
比如1 2 5 4 3 6 7 8 9,最长的A序列子串是1 2 5 4 3。

输入

多组输入,每组两行。

第一行是n,表示给的数组的长度。

第二行有n个数(int范围),即给你的数组。
1<=n<=500000。

输出

每组输入输出一行,即最长的A序列子串的长度。

样例输入1
9
1 2 5 4 3 6 7 8 9


样例输出1
5

#include<stdio.h>
#include<map>
#include<string.h>
using namespace std;
int a[500010];
int a1[500010];
int b1[500010];
int g[500010];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
memset(a1,0,sizeof(a1));
memset(b1,0,sizeof(b1));
memset(g,0,sizeof(g));
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
g[1]=a[1];
int len=1;
a1[1]=1;
for(int i=1;i<n;i++)
{
if(a[i]>g[len])
{
len++;
g[len]=a[i];
a1[i]=len;
}
else
{
int pos=lower_bound(g+1,g+len+1,a[i])-g;
g[pos]=a[i];
a1[i]=pos;
}
}
memset(g,0,sizeof(g));
g[1]=a
;
len=1;
b1[1]=1;
for(int i=n-1;i>=1;i--)
{
if(a[i]>g[len])
{
len++;
g[len]=a[i];
b1[i]=len;
}
else
{
int pos=lower_bound(g+1,g+len+1,a[i])-g;
g[pos]=a[i];
b1[i]=pos;
}
}
int max_=0;
for(int i=1;i<=n;i++)
{
int temp=min(a1[i],b1[i]);
if(temp>max_)
{
max_=temp;
}
}
printf("%d\n",max_*2-1);

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  最长上升子序列