• 吉哥系列故事——完美队形II(马拉车算法)


    吉哥又想出了一个新的完美队形游戏!
      假设有n个人按顺序站在他的面前,他们的身高分别是h[1], h[2] ... h[n],吉哥希望从中挑出一些人,让这些人形成一个新的队形,新的队形若满足以下三点要求,则就是新的完美队形:

      1、挑出的人保持原队形的相对顺序不变,且必须都是在原队形中连续的;
      2、左右对称,假设有m个人形成新的队形,则第1个人和第m个人身高相同,第2个人和第m-1个人身高相同,依此类推,当然如果m是奇数,中间那个人可以任意;
      3、从左到中间那个人,身高需保证不下降,如果用H表示新队形的高度,则H[1] <= H[2] <= H[3] .... <= H[mid]。

      现在吉哥想知道:最多能选出多少人组成新的完美队形呢?

    Input  输入数据第一行包含一个整数T,表示总共有T组测试数据(T <= 20);
      每组数据首先是一个整数n(1 <= n <= 100000),表示原先队形的人数,接下来一行输入n个整数,表示原队形从左到右站的人的身高(50 <= h <= 250,不排除特别矮小和高大的)。Output  请输出能组成完美队形的最多人数,每组输出占一行。Sample Input

    2
    3
    51 52 51
    4
    51 52 52 51

    Sample Output

    3
    4

    题意:

    就是让你找到一个最长回文子串,如果这个串是偶数,那么他的左边一半就要满足i<j且Ai<=Aj,也就是非严格递增类型

    如果是奇数,那么中间那个数大小可以不受限制

    题解:

    就是在马拉车算法里面加一个判断,只是我前边那一种写的太麻烦了,所以超时了

    具体看代码:

      1 //#include<stdio.h>
      2 //#include<string.h>
      3 //#include<iostream>
      4 //#include<algorithm>
      5 //#include<set>
      6 //using namespace std;
      7 //const int maxn=300005;
      8 //const int INF=0x3f3f3f3f;
      9 //const int mod=998244353;
     10 //int str[maxn],s[maxn];
     11 //int len,Len[maxn];
     12 //void init()
     13 //{
     14 //    memset(str,0,sizeof(str));
     15 //    int k=0;
     16 //    str[k++]=10000;
     17 //    for(int i=0;i<len;++i)
     18 //        str[k++]=1000,str[k++]=s[i];
     19 //    str[k++]=1000;
     20 //    len=k;
     21 //}
     22 //int manacher()
     23 //{
     24 //    Len[0]=0;
     25 //    int sum=0;
     26 //    int mx=0,id;
     27 //    for(int i=1;i<len;++i)
     28 //    {
     29 //        if(i<mx) Len[i]=min(mx-i,Len[2*id-i]);
     30 //        else Len[i]=1;
     31 //        while(str[i-Len[i]]==str[i+Len[i]]) Len[i]++;
     32 //        if(Len[i]+i>mx)
     33 //        {
     34 //            mx=Len[i]+i;
     35 //            id=i;
     36 //            int flag=0;
     37 //            if((Len[i]-1)%2)
     38 //            {
     39 //                if(Len[i]-1>=5)
     40 //                for(int j=i-4;j>j-Len[i];j-=2)
     41 //                {
     42 //                    if(str[j]>str[j+2])
     43 //                    {
     44 //                        flag=1;
     45 //                        break;
     46 //                    }
     47 //                }
     48 //            }
     49 //            else
     50 //            {
     51 //                if(Len[i]-1>=4)
     52 //                for(int j=i-3;j>j-Len[i];j-=2)
     53 //                {
     54 //                    if(str[j]>str[j+2])
     55 //                    {
     56 //                        flag=1;
     57 //                        break;
     58 //                    }
     59 //                }
     60 //            }
     61 //            if(!flag)
     62 //            sum=max(sum,Len[i]);
     63 //        }
     64 //    }
     65 //    return sum-1;
     66 //}
     67 //int main()
     68 //{
     69 //    int t;
     70 //    scanf("%d",&t);
     71 //    while(t--)
     72 //    {
     73 //        memset(s,0,sizeof(s));
     74 //        scanf("%d",&len);
     75 //        for(int i=0;i<len;++i)
     76 //            scanf("%d",&s[i]);
     77 //        init();
     78 //        printf("%d
    ",manacher());
     79 //    }
     80 //    return 0;
     81 //}
     82 #include<stdio.h>
     83 #include<string.h>
     84 #include<iostream>
     85 #include<algorithm>
     86 #include<set>
     87 using namespace std;
     88 const int maxn=300005;
     89 const int INF=0x3f3f3f3f;
     90 const int mod=998244353;
     91 int str[maxn],s[maxn];
     92 int len,Len[maxn];
     93 void init()
     94 {
     95     memset(str,0,sizeof(str));
     96     int k=0;
     97     str[k++]=-1;
     98     for(int i=0;i<len;++i)
     99         str[k++]=0,str[k++]=s[i];
    100     str[k++]=0;
    101     len=k;
    102 }
    103 void manacher()
    104 {
    105     Len[0]=0;
    106     int sum=0;
    107     int id,mx=0;
    108     for(int i=1;i<len;++i)
    109     {
    110         if(i<mx)  Len[i]=min(mx-i,Len[2*id-i]);
    111         else Len[i]=1;
    112         int Min;
    113         if(str[i] > 0) Min = str[i];
    114         else Min = str[i + 1];
    115         while(str[i - Len[i]] == str[i + Len[i]] && str[i - Len[i]] <= Min) {
    116             //printf("are you here?
    ");
    117             if(str[i - Len[i]] > 0)
    118                 Min = str[i - Len[i]];
    119             if(i + Len[i] > mx) {
    120                 mx = i + Len[i];
    121                 id = i;
    122             }
    123             Len[i]++;
    124         }
    125     }
    126     int ans = 0;
    127     for(int i = 1; i < len; i++) ans = max(ans, Len[i]);
    128     printf("%d
    ", ans - 1);
    129 }
    130 //        if(Len[i]+i>mx)
    131 //        {
    132 //            mx=Len[i]+i;
    133 //            id=i;
    134 //            int flag=0;
    135 //            if((Len[i]-1)%2)
    136 //            {
    137 //                if(Len[i]-1>=5)
    138 //                for(int j=i-4;j>j-Len[i];j-=2)
    139 //                {
    140 //                    if(str[j]>str[j+2])
    141 //                    {
    142 //                        flag=1;
    143 //                        break;
    144 //                    }
    145 //                }
    146 //            }
    147 //            else
    148 //            {
    149 //                if(Len[i]-1>=4)
    150 //                for(int j=i-3;j>i-Len[i];j-=2)
    151 //                {
    152 //                    if(str[j]>str[j+2])
    153 //                    {
    154 //                        flag=1;
    155 //                        break;
    156 //                    }
    157 //                }
    158 //            }
    159 //            if(!flag)
    160 //            sum=max(sum,Len[i]);
    161 //        }
    162 //    }
    163 //    return (sum-1);
    164 //}
    165 int main()
    166 {
    167     int t;
    168     scanf("%d",&t);
    169     while(t--)
    170     {
    171         scanf("%d",&len);
    172         for(int i=0;i<len;++i)
    173             scanf("%d",&s[i]);
    174         init();
    175         manacher();
    176         //printf("%d
    ",);
    177     }
    178     return 0;
    179 }
    View Code
  • 相关阅读:
    转:验证日期的正则表达式比较全面地验证
    IIS应用地址池监控
    Net预编译 真的好用与否
    关键字检索,找到所有数据
    vue 文件上传自定义实现
    docker 基础(一)
    input表单中嵌入百度地图
    linux系统光盘开机自动挂载-配置本地yum源
    linux学习笔记基础篇(一)
    构建apache web 服务器
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/11271249.html
Copyright © 2020-2023  润新知