UVA 10534-Wavio Sequence(dp_正序逆序最长上升子序列)
Description
Problem D
Wavio Sequence
Input: Standard Input
Output: Standard Output
Time Limit: 2 Seconds
Wavio is a sequence of integers. It has some interesting properties.
· Wavio is of odd length i.e. L = 2*n + 1.
· The first (n+1) integers of Wavio sequence makes a strictly increasing sequence.
· The last (n+1) integers of Wavio sequence makes a strictly decreasing sequence.
· No two adjacent integers are same in a Wavio sequence.
For example 1, 2, 3, 4, 5, 4, 3, 2, 0 is an Wavio sequence of length 9. But 1, 2, 3, 4, 5, 4, 3, 2, 2 is not a valid wavio sequence. In this problem, you 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. Consider, the given sequence as :
1 2 3 2 1 2 3 4 3 2 1 5 4 1 2 3 2 2 1.
Here the longest Wavio sequence is : 1 2 3 4 5 4 3 2 1. So, the output will be 9.
Input
The input file contains less than 75 test cases. The description of each test case is given below: Input is terminated by end of file.
Each set starts with a postive integer, N(1<=N<=10000). In next few lines there will be N integers.
Output
For each set of input print the length of longest wavio sequence in a line.
Sample Input Output for Sample Input
10 1 2 3 4 5 4 3 2 1 10 19 1 2 3 2 1 2 3 4 3 2 1 5 4 1 2 3 2 2 1 5 1 2 3 4 5 |
9 9 1
|
Problemsetter: Md. Kamruzzaman, Member of Elite Problemsetters‘ Panel
Wavio是一个整数序列,具有以下特性:
1、Wavio序列的长度是奇数, 即 L = 2 * n + 1;
2、Wavio序列前 n+1 个整数是递增序列
3、Wavio序列后 n+1 个整数是递减序列
如示例 1 2 3 4 5 4 3 2 1 10
最长的 Wavio序列 为 1 2 3 4 5 4 3 2 1 ,所以答案为9
对于输入序列中的一个整数 ai ,我们设以 ai 为尾的前缀的最长递增序列的长度为Fi ,如在示例1中对已第3个整数3,从头开始,以3为尾的递增序列为1 2 3 ,所以F3=3;
以ai为首的后缀的递减序列的长度为Gi, 如示例1中第3个整数,以3为开始,递减序列为3 2 1,所以G3=3 (可以看做求从最后一个元素出发,到3这个位置的最大递增序列,为1 2 3,所以G3=3)
在我们找递减序列的时候,可以看做从最后一个元素出发,到当前位置的最大递增序列,这样我们对于每一个元素ai 我们可以先求出 a0到ai最大递增序列 和 an-1到ai的最大递增序列 ,这样我们可以得到ai的Wavio序列的值为
2*min( Fi , Gi) - 1 ,最后的结果是这些Wavio序列中的一个最大值。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <map>
#include <string>
using namespace std;
const int inf=0x3f3f3f3f;
int binsearch(int *a,int r,int key)
{
int l=0;
int mid=(l+r)/2;
while(l<=r){
if(a[mid]<key)
l=mid+1;
else if(a[mid]>key)
r=mid-1;
else
return mid;
mid=(l+r)/2;
}
return l;
}
int main()
{
int n,i;
while(~scanf("%d",&n)){
int a[10010],b[10010],c[10010];//b保存的是以a[i]为结尾的最长递增子序列,c保存长度为i的递增子序列的最末的元素,c是单调递增的
int a1[10010],b1[10010],c1[10010];//同上
for(i=0;i<n;i++){
scanf("%d",&a[i]);
a1[n-i-1]=a[i];
}
for(i=0;i<n;i++)
c[i]=inf;
c[0]=-1;
c[1]=a[0];//保存了长度为1时的递增序列的最末的元素,且此时长度为1的递增了序列只有一个,c[1]也是最小的;
b[0]=1;//此时以a[0]结尾的最长递增子序列的长度为1.
for(i=1;i<n;i++){
int j=binsearch(c,n,a[i]);
c[j]=a[i];
b[i]=j;
}
for(i=0;i<n;i++)
c1[i]=inf;
c1[0]=-1;
c1[1]=a1[0];
b1[0]=1;
for(i=1;i<n;i++){
int j=binsearch(c1,n,a1[i]);
c1[j]=a1[i];
b1[i]=j;
}
int res=0;
for(i=0;i<n;i++){
res=max(res,min(b[i],b1[n-i-1]));
}
printf("%d\n",res*2-1);
}
return 0;
}