SHoj A序列

A序列

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

如果一个序列有奇数个正整数组成,不妨令此序列为,,,...,2k+1   (0<= ),并且,...k+1   是一个严格递增的序列,k+,k+,...,2k+1   ,是一个严格递减的序列,则称此序列是A序列。

比如1 2 5 4 3就是一个A序列。

现在Jazz有一个长度为 的数组,他希望让你求出这个数组所有满足A序列定义的子序列里面最大的那个长度。(子序列可以不连续)

比如1 2 5 4 3 6 7 8 9,最长的A序列子串是1 2 5 4 3。

多组输入,每组两行。
第一行是 ,表示给的数组的长度。
第二行有 个数(int范围),即给你的数组。
1<=n<=500000 

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

复制
9
1 2 5 4 3 6 7 8 9
5

思路:我们遍历序列中每一个数字看看,对于每一个数字ai,以ai为中心,能得到的最长A序列是多少,这时先得到ai左边序列(以ai为序列末尾)的最长上升子序列left[i],再得到ai右边序列(包括ai)的最长下降子序列,最长下降子序列相当于序列倒着排的最长上升子序列,求得为right[i];
按A序列定义,ai的左右两边数字个数应该相等,那要使得ai为中心的A序列尽量大,可以去min(left[i],right[i])为A序列的长度的一半,2*min(left[i],right[i])-1即是以ai为中心A序列的最大长度,遍历ai,求最大长度。

AC代码:

#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<string>
#include<stack>
#include<algorithm>
using namespace std;
#define INF 0x3f3f3f3f
const int N_MAX = 500000+2;
vector<int>vec;
int dp[N_MAX];
int Right[N_MAX], Left[N_MAX];
int n;
void LIS(const vector<int>&vec,int *a) {
    fill(dp,dp+n,INF);
    for (int i = 0; i < n;i++) {
        *lower_bound(dp,dp+n,vec[i])=vec[i];
        a[i] = lower_bound(dp, dp + n, INF) - dp;
    }
}
int main() {
    
    while (scanf("%d",&n)!=EOF) {
        vec.clear();
        vec.resize(n);
        for (int i = 0; i < n;i++) 
            scanf("%d",&vec[i]);
        int ans=0;
        LIS(vec,Left);
        reverse(vec.begin(), vec.end());
        LIS(vec, Right);
        int res=0;
        for (int i = 0; i < n;i++) {
            int ans = min(Right[i], Left[n-i]);
            res = max(res, ans);
        }
        printf("%d\n",2*res-1);
    }
    return 0;
}

 

posted on 2017-07-19 16:28  ZefengYao  阅读(383)  评论(0编辑  收藏  举报

导航