• hdu4513完美队形II manacher


      吉哥又想出了一个新的完美队形游戏! 
      假设有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

    题意:找最长非递减子序列

    思路:manacher算法 中间判断一下是不是非递减 如果递减了就不要让pi继续增大了

    代码:

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #define inf 0x3f3f3f3f
    
    using namespace std;
    
    int t, n;
    int height[100005], nhei[200005];
    
    int init()
    {
        int j = 0;
        nhei[j] = -1;j++;
        for(int i = 0; i < n; i++){
            nhei[j] = -2;j++;
            nhei[j] = height[i];j++;
        }
        nhei[j] = -2;j++;
        //nhei[j] = -1;
    
        return j;
    }
    
    int manacher()
    {
        int p[200005];
        int len = init();
        int maxlen = -1;
    
        int id;
        int mx = 0;
        //p[0] = 0;
    
        for(int i = 0; i < len; i++){
            if(i < mx){
                p[i] = min(p[2 * id - i], mx - i);
            }
            else{
                p[i] = 1;
            }
    
            while(nhei[i - p[i]] == nhei[i + p[i]]){
                if(nhei[i - p[i]] != -2){
                    if(nhei[i + p[i]] <= nhei[i + p[i] - 2]){
                        p[i]++;
                    }
                    else{
                        break;
                    }
                }
                p[i]++;
            }
    
            if(mx < i + p[i]){
                id = i;
                mx = i + p[i];
            }
    
            maxlen = max(maxlen, p[i]);
        }
    
        return maxlen;
    }
    
    int main()
    {
        cin>> t;
        while(t--){
            cin>>n;
            for(int i = 0; i < n; i++){
                scanf("%d",&height[i]);
            }
    
            int ans = manacher() - 1;
            cout<< ans<< endl;
        }
    	return 0;
    }
    
  • 相关阅读:
    java例题 汽油检测
    java常用api
    二分搜索法
    java例题
    java基础
    表单验证
    4.10 pm例题
    0805
    0731 框架Mybatis
    小结
  • 原文地址:https://www.cnblogs.com/wyboooo/p/9643435.html
Copyright © 2020-2023  润新知