HOJ 2985 Wavio Sequence(最長インクリメントサブシーケンスおよびそのO(n*logn)アルゴリズム)
5905 ワード
Wavio Sequence My Tags(Edit)Source:UVA Time limit:1 sec Memorylimit:32 M Submitted:296,Acctepted:123 Wavio is a sequence of integers.It has some interestititititities.Wavio is is properties.Wavio isisis propertities.Waviis.Wavis.Waviisisisisisisisisisisis propertities.Wavidededededededededededededededededededededededededededededededededededededededededededededededededeties.Wavi. The last(n+1)integers of Wavio sequence makes a strictly decreasung sequence.No two adjacent integers are same in a Wavio sequence.For example 1,2,4,4,4,3,2,0 is Wavio sequence of length 9.But 3,prores 2,5You will be given a sequence of integers.You have to find out the length of the longest Wavio sequence which is a subsequence of the given sequence.Consder,the given sequence as:1 3 3 3.Heven 2the output will be 9.Input The input file contains multile test cases.The description of each test case is given below.Input is terminated by of file.Each set starts with a postive integer,N(1≦)10000In next fewラインthere will be N integers.Output For each set of input print the length of longest wavio sequence in a line.Sample Input 10 1 2 4 4 4 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 3 3 3 3 O 2 2 2 2 3 3 3 3 put 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 mp 3 3 3 3 3 3 3 3 3 3 3 3 3 mp 5 e 1
解法は、配列を正と逆にして、それぞれの最長の増分サブシーケンスを求めて、iを遍歴しています.i左の配列と右の配列の最長男シーケンスが等しいなら、条件に合致します.最長インクリメントサブシーケンスを求める場合はO(N^2)でタイムアウトしますので、効率の高いアルゴリズムを使用しなければなりません.Oアルゴリズムについては以下のブログを参照してください.http://blog.csdn.net/dacc123/article/details/50571844 コードを付ける
解法は、配列を正と逆にして、それぞれの最長の増分サブシーケンスを求めて、iを遍歴しています.i左の配列と右の配列の最長男シーケンスが等しいなら、条件に合致します.最長インクリメントサブシーケンスを求める場合はO(N^2)でタイムアウトしますので、効率の高いアルゴリズムを使用しなければなりません.Oアルゴリズムについては以下のブログを参照してください.http://blog.csdn.net/dacc123/article/details/50571844 コードを付ける
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <algorithm>
using namespace std;
int a[10005];
int b[10005];
int c[10005];
int d[10005];
int dp[10005];
int bp[10005];
int n;
int ans;
int search(int num,int l,int r,int *dp)
{
int mid;
while(l<=r)
{
mid=(l+r)/2;
if(num>dp[mid])
l=mid+1;
else
r=mid-1;
}
return l;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
ans=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
b[n-i+1]=a[i];
}
//memset(dp,0,sizeof(dp));
dp[1]=a[1];
c[1]=1;
int len=1;
for(int i=2;i<=n;i++)
{
if(a[i]>dp[len])
dp[++len]=a[i];
else
{
int pos=search(a[i],1,len,dp);
dp[pos]=a[i];
}
c[i]=len;
}
bp[1]=b[1];
d[1]=1;
int len2=1;
for(int i=2;i<=n;i++)
{
if(b[i]>bp[len2])
bp[++len2]=b[i];
else
{
int pos=search(b[i],1,len2,bp);
bp[pos]=b[i];
}
d[i]=len2;
}
for(int i=1;i<=n;i++)
{
if(c[i]==d[n-i+1])
ans=max(ans,c[i]*2-1);
}
printf("%d
",ans);
}
return 0;
}