zoukankan      html  css  js  c++  java
  • HDU 4513吉哥系列故事——完美队形II Manacher

    HDU 4513吉哥系列故事——完美队形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]

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

    解题思路

    看到这里序列的特殊要求实际上不就是个回文串嘛,那肯定就是Manacher算法了。

    关键是如何处理大小关系呢,这里是在模板中加了一些判断就可以解决:

    1. 中间插入的不再是字符,而是数字,这里我们插入0x3f3f3f3f这个来进行代替。
    2. 在判断完对称的数字相等之后还要判断是否小于,这里需要知道两个实际的数之间有我们插的数,这个需要注意。
    3. 其他细节看代码。

    代码实现

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int inf=0x3f3f3f3f;
    const int maxn=1e5+7;
    int num[maxn], tmp[maxn<<1];
    int p[maxn<<1]; 
    int t, n;
    void init()
    {
    	tmp[0]=inf+1;
    	for(int i=1; i<=2*n; i+=2)
    	{
    		tmp[i] = inf;
    		tmp[i+1] = num[i>>1];
    	}
    	tmp[(n<<1)+1]=inf;
    	tmp[(n<<1)+2]=inf+1;
    }
    int manacher(int *st, int len)
    {
    	int mx=0, ans=0, po=0;
    	for(int i=1; i<=len; ++i)
    	{
    		if(mx > i)
    			p[i]=min( mx-i, p[ (po<<1) - i ] );
    		else 
    			p[i]=1;
    		while(st[ i - p[i]] ==st[ i + p[i]] )
    		{
    			if( st[ i-p[i] ] == inf)
    				p[i]++;
    			else if(st[ i-p[i] ] <= st[ i-p[i]+2 ])
    				p[i]++;
    			else break;
    		}
    		if(p[i]+i>mx)
    		{
    			mx=p[i]+i;
    			po=i;
    		}
    		ans=max(ans, p[i]);
    	}
    	return ans-1;
    }
    int main()
    {
    	scanf("%d", &t);
    	while(t--)
    	{
    		scanf("%d", &n);
    		for(int i=0; i<n; i++)
    			scanf("%d", &num[i]);
    		init();
    //		for(int i=1; i<=2*n+1; i++)
    //			printf("%d ", tmp[i]);
    //		printf("
    ");
    		int ans=manacher(tmp, n*2+1);
    		printf("%d
    ", ans);
    	}
    	return 0;
     } 
    
  • 相关阅读:
    Oracle数据库-建库、建表空间,建用户
    创建oracle数据库的表空间、用户、目录、导入导出文件等信息
    使用 UML 进行业务建模:理解业务用例与系统用例的相似和不同之处
    DataSet用法详细
    DataSet和DataTable详解
    经典SQL语句集锦
    JS脚本验证大全
    用Unity写一个12306验证器的恶搞图生成软件
    SQL Server中 sysobjects、syscolumns、systypes
    如何在oracle中导入导出(备份&恢复)dmp数据库文件
  • 原文地址:https://www.cnblogs.com/alking1001/p/12248537.html
Copyright © 2011-2022 走看看