HDU-3613 Best Reward (Manacher)

题目:

http://acm.hdu.edu.cn/showproblem.php?pid=3613

题意:

最大价值回文串组合,要求把整个字符串拆成两个串,求可能的最大价值和。每个串只有是回文串时才会有价值,价值是这个串中所有字母的价值之和,会给出每个字母的价值。

注意必须分成两个串每个串的长度至少唯一。

思路:

 Manacher算法是通过对称位置快速处理回文串的方法,求出一个p[]数组,p[i] 表示第i个字符为中心展开的最大回文串的长度。

依次枚举一遍所有点为第一个子串中心点时可以取得的最大价值,因为 Manacher对原字符串的所有字符之间插入‘#’,所以通过‘#’展开就可以处理偶数串的情况。

代码:

#include <bits/stdc++.h>
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define EPS 1e-6
#define N 1123456
using namespace std;
int n,m,sum,res,flag;
int a[30];
char s[N];
int p[N],f[N];
int Manacher(char *str, int len)
{
    int res=0,ans=0;
    for(int i=len;i>=0;i--)
    {
        str[i+i+2] = str[i];
        str[i+i+1] = '#';
    }
    str[0] = '*';
    for(int i=2;i<2*len+1;i++)
    {
        if(p[res]+res > i)
            p[i] = min(p[2*res-i],p[res]+res-i);
        else
            p[i] = 1;
        while(str[i-p[i]] == str[i+p[i]])
            p[i]++;
        if(res+p[res]<i+p[i])res=i;
        if(ans<p[i])ans=p[i];
    }
    return ans-1;
}
int main()
{
    int i,j,k,kk,cas,T,t,x,y,z;
    scanf("%d",&T);
    cas=0;
    while(T--)
    {
        for(i=0;i<26;i++)
            scanf("%d",&a[i]);
        scanf("%s",s);
        n=strlen(s);
        Manacher(s,n);
        m=strlen(s);
        f[0]=0;res=0;
        for(i=1;i<m;i++)
            f[i]=f[i-1]+(s[i]=='#'?0:a[s[i]-'a']);
        for(i=1;i<m;i++)
        {
            if(i==p[i])
            {
                x=i+p[i]-1;y=m-1;z=(x+y)/2;
                t=f[x];
                if(p[z]+z==m)t=f[m-1];
                if(x==y)t=0;
                res=max(res,t);
            }
            else if(i+p[i]==m)
                t=f[m-1]-f[i-p[i]],res=max(res,t);;
        }
        printf("%d\n",res);
    }
    return 0;
}











  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值