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;
    }
    
  • 相关阅读:
    Smart Client Architecture and Design Guide
    Duwamish密码分析篇, Part 3
    庆贺发文100篇
    .Net Distributed Application Design Guide
    New Introduction to ASP.NET 2.0 Web Parts Framework
    SPS toplevel Site Collection Administrators and Owners
    来自Ingo Rammer先生的Email关于《Advanced .Net Remoting》
    The newsletter published by Ingo Rammer
    深度探索.Net Remoting基础架构
    信道、接收器、接收链和信道接受提供程序
  • 原文地址:https://www.cnblogs.com/alking1001/p/12248658.html
Copyright © 2011-2022 走看看