zoukankan      html  css  js  c++  java
  • HDU 3613 Best Reward Manacher算法

    HDU 3613 Best Reward Manacher算法

    题意

    字符串,需要把这个字符串分成两段,并使得被分开的两段价值和最大。

    一个串如果是回文,那么它的价值就是所有字符的价值和,否则价值为0。每个字母都有相应的价值,这个会给出。

    解题思路

    使用Manacher,我们可以算出每个点的回文串长度,然后我们枚举左半部分的长度(这样很容易算出中心点),进而知道以这个中心点的回文串长度是不是等于这个左半部分的长度。这样来判断。

    对于价值,我们可以使用前缀和来提前算好,这样用的话就可以直接用了。下节的代码实现对应这个算法。

    搜了一下题解,还有发现使用拓展KMP也可以,思路上也比较简单。
    想要看的话可以点击这个链接:https://blog.csdn.net/u013480600/article/details/23041391

    代码实现

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int inf=0x3f3f3f3f;
    const int maxn=5e5+7;
    char str[maxn], s[maxn<<1];
    int p[maxn<<1], newlen;
    int val[26], presum[maxn];
    void init(int n)
    {
    	newlen=n<<1;
    //	s[0]='$';
    	for(int i=0; i<=newlen+1; i++) s[i]='#';
    	for(int i=1; i<=n; i++) s[i<<1]=str[i];
    	s[newlen+2]=0;
    }
    void manacher()
    {
    	int mx=0,id=0;
    	for(int i=1;i<=newlen;i++)
    	{
    		if(mx>i) p[i]=min(p[2*id-i],mx-i);
    		else p[i]=1;
     
    		while(i-p[i]>=0&&s[i-p[i]]==s[i+p[i]]) p[i]++;
    		if(i+p[i]>mx) 
    		{
    			mx=i+p[i];
    			id=i;
    		}
    	}
    }
    int main()
    {
    	int t=0;
    	scanf("%d",&t);
    	while(t--)
    	{
    		for(int i=0; i<26; i++)	scanf("%d", &val[i]);
    		scanf("%s", str+1);
    		int len=strlen(str+1);
    		presum[0]=0;
    		for(int i=1; i<=len; i++)
    			presum[i] = presum[i-1] + val[ str[i]-'a'];
    		init(len);
    		manacher();
    //		for(int i=1; i<=newlen; i++)
    //			printf("%d ", p[i]);
    //		printf("
    ");
    		int ans=-inf;
    		for(int cut=1; cut<len; cut++)
    		{
    			int temp=0;
    			int len1=cut, len2=len-len1;
    			if(len1%2 == 1)
    			{
    				int mid=len1/2+1;
    				int palen=p[mid<<1]-1; //mid<<1,这里是对应的实际位置 
    				if(len1 == palen) temp+=presum[len1]; 
    			}
    			else 
    			{
    				int mid=len1/2;
    				int palen=p[mid*2+1]-1;
    				if(len1 == palen ) temp+=presum[len1];
    			}
    			if(len2%2==1)
    			{
    				int mid=len1+len2/2+1;
    				int palen=p[mid<<1]-1;
    				if(len2 == palen) temp += presum[len] - presum[len1];
    			}
    			else 
    			{
    				int mid=len1+len2/2;
    				int palen=p[mid*2+1]-1;
    				if(len2 == palen ) temp += presum[len] - presum[len1];
    			}
    			if(temp>ans) ans=temp;
    		}
    		printf("%d
    ", ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    用 VMControl 管理 IBM i,第 1 部分: VMControl 简介
    使用 VMControl 2.4 实现多网络的 Power 服务器捕捉和系统部署
    lftp 4.4.0 发布,命令行的FTP工具
    Percona Toolkit 2.1.4 发布
    RabbitMQ 2.8.7 发布,AMQP 消息队列
    编程获取本机IPv4及IPv6地址
    Mac下android环境搭建
    Python 3.3.0 RC3 发布
    Sean Lynch谈Facebook Claspin监控工具的由来
    .NET开发者可以在Windows 8中使用ARM
  • 原文地址:https://www.cnblogs.com/alking1001/p/12248658.html
Copyright © 2011-2022 走看看