UVa 10534 Wavio Sequence

UVa 10534 Wavio Sequence

链接:https://vjudge.net/problem/UVA-10534

思路:

 分别列出每个数列的最长上升子序列(LIS)和最长下降子序列(LDS)

注:LIS(i):以a[i]结尾的最长上升子序列长度 LDS:以a[i]为开头的最长下降子序列长度
如:
数列:1 2 3 4 5 4 3 2 1 10
LIS:  0 1 2 3 4 4 4 4 4 5
LDS:4 4 4 4 4 3 2 1 0 0
其中5 对应的LIS长度为4,LDS长度为4,答案n=min(4,4)=4 N=2*4+1=9
分别比对每个数对应的最长上升子序列长度和最长下降子序列长度中的最小值,选出最大的即可。
注:(1)要求LDS,只需要将数列反向进行一遍LIS即可。 (2) 由于N的范围可能达到10000,LIS:N^2的算法有可能会超时,因此采用了NlogN 的优化算法
AC代码:
#include <bits/stdc++.h> 
using namespace std;
const int N=10000+10;
int a[N],dp[N], lis[N],lds[N];
int main()
{
    int n;
    while (scanf("%d", &n) != EOF){
        for (int i=0;i<n;i++) scanf("%d",&a[i]);
         memset(dp,0,sizeof(dp));
        int pos=0;   
        dp[0]=a[0];lis[0]=0;
        for(int i=1; i<n; i++)
        {
            if(a[i]>dp[pos]) 
                dp[++pos] = a[i];
            else  
                dp[lower_bound(dp,dp+pos+1,a[i])-dp]=a[i];  
            lis[i]=pos;
        }
        memset(dp,0,sizeof(dp));
        pos=0;   
        dp[0]=a[n-1];lds[n-1]=0;
        for(int i=n-1; i>=0; i--)
        {
            if(a[i]>dp[pos]) 
                dp[++pos] = a[i];
            else  
                dp[lower_bound(dp,dp+pos+1,a[i])-dp]=a[i];  
            lds[i]=pos;
        }
        int ans=0;
        for (int i=0;i<n;i++)
            ans=max(ans,min(lis[i],lds[i]));
        printf("%d\n",ans*2+1);
    }
    
    return 0;
}

 

猜你喜欢

转载自www.cnblogs.com/chillilly/p/12732975.html
今日推荐