606第七周周赛 C - Wavio Sequence最长递增递减序列





给定一串数字,求一个子串满足一下要求:子串的长度是L=2*n+1,前n+1个数字是严格的递增序列,后n+1个数字是严格的递减序列,例如123454321就是满足要求的一个子串,输出满足要求的最长的L,

2、正着走一遍LIS,再倒着走一遍LIS,dp[i]表示前i个满足要求的数字的个数,那么dp1[i]和dp2[i]中最小的一个就是L的一半





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
const int INF=999999999;
const int M=10010;
int dp1[M],dp2[M],g[M],t[M];
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        memset(dp1,0,sizeof(dp1));
        memset(dp2,0,sizeof(dp2));
        for(int i=1; i<=n; i++)
            scanf("%d",&t[i]);
        fill(g,g+n,INF);   
        //将一个区间里的元素都赋予INF值
        for(int i=1;i<=n;i++)     //寻找最长递增子序列
        {
            int k=lower_bound(g+1,g+n+1,t[i])-g;
              //返回一个非递减序列中的第一个大于等于t[i]的位置
            g[k]=t[i];
            dp1[i]=max(dp1[i-1],k);
        }
        fill(g,g+n,INF);      //反向,寻找最长递减子序列
        for(int i=n; i>=1; i--)
        {
            int k=lower_bound(g+1,g+n+1,t[i])-g;
            g[k]=t[i];
            dp2[i]=max(dp2[i+1],k);
        }
        int m=0;
        for(int i=1; i<=n; i++)
            m=max(m,min(dp1[i],dp2[i]));
            //找出最短的长度,才能保证是最长序列
        printf("%d\n",2*m-1);
    }
    return 0;
}

你可能感兴趣的:(606第七周周赛 C - Wavio Sequence最长递增递减序列)