程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> HDU 4513 吉哥系列故事――完美隊形II(Manacher)

HDU 4513 吉哥系列故事――完美隊形II(Manacher)

編輯:關於C++

題意

  吉哥又想出了一個新的完美隊形游戲!
  假設有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]。

現在吉哥想知道:最多能選出多少人組成新的完美隊形呢?

思路

跟HDU 3068 最長回文(Manacher)差不多,也是求回文串長度,區別就是多了一個非遞減的約束條件,加上判斷即可。

代碼

#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

const int N = 100009;
int s[N*2], p[N*2];

int manacher(int len)
{
    int mx = 0, id = 0, ans = 1;
    p[0] = 0;
    for(int i=1; i i)
            p[i] = min(mx-i, p[2*id-i]);
        while(s[i-p[i]] == s[i+p[i]] && s[i-p[i]] <= s[i-p[i]+2])
            p[i]++;
        if(i+p[i] > mx)
            mx = i+p[i], id = i;
        if(ans < p[i]-1)
            ans = p[i]-1;
    }
    return ans;
}

int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        int n;
        scanf("%d", &n);
        s[0] = -1;
        for(int i=1; i<=n; i++)
        {
            s[i*2-1] = 0;
            scanf("%d", &s[i*2]);
        }
        s[2*n+1] = 0;
        printf("%d\n", manacher(2*n+1));
    }
    return 0;
}
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved