传送门

题意:

  国王为了犒劳立下战功的大将军Li,决定奖给Li一串项链,这个项链一共包含26中珠子"a~z",每种珠子都有

  相应的价值(-100~100),当某个项链可以构成回文时,那么这个项链的价值就是每个珠子价值的加和,如果

  构不成,那么这个项链的价值就为0;

  求如何将国王奖赏的一串项链拆成价值加和最大的两串项链,求出这个最大价值。

题解:

  本来我是在找有关拓展KMP的相关题目的,百度到一大牛的博客(“扩展KMP题目”),当做到第二个题目的时候,

  思来想去,就是没找到其和拓展KMP的联系,然后,感觉可以用Manacher算法,刷刷刷撸了个Manacher的代码

  提交,AC,所以,我暂且谈谈如何用Manacher算法解这道题;

  ①首先将项链串s[]预处理(了解Manacher算法就理解啥意思了);

  ②准备一个数组sum[],sum[ i ]:预处理后的数组中前 i 个字符对应的价值的加和,'#'当作0;

  ③使用Manacher算法求解出回文半径数组radius[];

  ④假设从 i 位置切割项链,将项链分成[ 0,i ],[ i,len-1 ]两串,分别求解对应的总价值,令ans=max{从i位置分割的总价值}

 AC代码:
 #include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define INF 0x3f3f3f3f
#define lowbit(x) (x&-x)
#define mem(a,b) memset(a,b,sizeof(a))
const int maxn=5e5+; int val[];
char s[*maxn];
char temp[maxn];
int radius[*maxn];
int sum[*maxn];
void Trans()
{
int len=strlen(s);
strcpy(temp,s);
for(int i=;i < len;++i)
{
s[*i]='#';
s[*i+]=temp[i];
}
s[*len]='#';
s[*len+]='\0';
}
void Manacher()
{
mem(radius,);
int len=strlen(s);
int R=;
int K=;
radius[]=;
for(int i=;i < len;++i)
{
int cnt=;
if(i >= R)
{
while(i+cnt < len && i-cnt >= && s[i+cnt] == s[i-cnt])
cnt++;
radius[i]=cnt;
if(i+cnt- > R)
{
R=i+cnt-;
K=i;
}
}
else
{
int j=K-(i-K);
if(i+radius[j]- != R)
radius[i]=min(R-i+,radius[j]);
else
{
cnt=R-i+;
while(i-cnt >= && i+cnt < len && s[i-cnt] == s[i+cnt])
cnt++;
radius[i]=cnt;
if(i+cnt- > R)
{
R=i+cnt-;
K=i;
}
}
}
}
}
int Solve()
{
Trans();//预处理字符串s
Manacher(); int len=strlen(s);
sum[]=;
for(int i=;i < len;++i)//前缀和
sum[i]=sum[i-]+(s[i] == '#' ? :val[s[i]-'a']); int ans=-INF;
for(int i=;i < len-;i+=)
{
int cnt=;
int x=(i+)>>;//[0,i+1]的中点坐标
if(radius[x] == x+)//判断[0,i]是否构成回文子串
cnt += sum[i]; int y=(len+i)>>;//[i+1,len-1]的中点坐标
if(radius[y] == len-y)//判断[i+1,len-1]是否构成回文子串
cnt += sum[len-]-sum[i];
ans=max(ans,cnt);
}
return ans;
}
int main()
{
// freopen("C:/Users/hyacinthLJP/Desktop/stdin/contest","r",stdin);
int test;
scanf("%d",&test);
while(test--)
{
for(int i=;i < ;++i)
scanf("%d",val+i);
scanf("%s",s);
printf("%d\n",Solve());
}
return ;
}

hdu 3613"Best Reward"(Manacher算法)的更多相关文章

  1. HDU 3613 Best Reward(KMP算法求解一个串的前、后缀回文串标记数组)

    题目链接: https://cn.vjudge.net/problem/HDU-3613 After an uphill battle, General Li won a great victory. ...

  2. HDU 3613 Best Reward 正反两次扩展KMP

    题目来源:HDU 3613 Best Reward 题意:每一个字母相应一个权值 将给你的字符串分成两部分 假设一部分是回文 这部分的值就是每一个字母的权值之和 求一种分法使得2部分的和最大 思路:考 ...

  3. HDU 3613 Best Reward(manacher求前、后缀回文串)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3613 题目大意: 题目大意就是将字符串s分成两部分子串,若子串是回文串则需计算价值,否则价值为0,求分 ...

  4. HDU - 3613 Best Reward(manacher或拓展kmp)

    传送门:HDU - 3613 题意:给出26个字母的价值,然后给你一个字符串,把它分成两个字符串,字符串是回文串才算价值,求价值最大是多少. 题解:这个题可以用马拉车,也可以用拓展kmp. ①Mana ...

  5. hdu 3613 Best Reward

    After an uphill battle, General Li won a great victory. Now the head of state decide to reward him w ...

  6. HDU3613 Best Reward —— Manacher算法 / 扩展KMP + 枚举

    题目链接:https://vjudge.net/problem/HDU-3613 Best Reward Time Limit: 2000/1000 MS (Java/Others)    Memor ...

  7. HDU 3613 Best Reward(拓展KMP算法求解)

    题目链接: https://cn.vjudge.net/problem/HDU-3613 After an uphill battle, General Li won a great victory. ...

  8. hdu 3613 Best Reward (manachar算法)

    Best Reward Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Prob ...

  9. HDU 3613 Best Reward ( 拓展KMP求回文串 || Manacher )

    题意 : 给个字符串S,要把S分成两段T1,T2,每个字母都有一个对应的价值,如果T1,T2是回文串,那么他们就会有一个价值,这个价值是这个串的所有字母价值之和,如果不是回文串,那么这串价值就为0.问 ...

随机推荐

  1. 阿里云ECS服务器,CentOS 7.4配置jdk+tomcat+mysql

    参考博客: https://mp.weixin.qq.com/s?__biz=MzIxMzk3Mjg5MQ==&mid=2247484020&idx=1&sn=6e0aa07f ...

  2. 一、纯css实现顶部进度条随滚动条滚动

    一.效果图 二.直接复制粘贴 <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...

  3. Running ASP.NET Core applications on Windows Subsystem for Linux

    Setting up Linux on Windows 10 First thing is to enable Windows Subsystem for Linux. It doesn’t inst ...

  4. centOS7 下配置和启动maria数据库

    从最新版本的linux系统开始,默认的是 Mariadb而不是mysql! 使用系统自带的repos安装很简单: yum install mariadb mariadb-server systemct ...

  5. CSS3 flexbox 布局 ---- flex项目属性介绍

    现在介绍用在flex项目上的css 属性,html结构还是用ul, li 结构,不过内容改成1,2,3, 样式的话,直接把给 ul 设display:flex 变成flex 容器,默认主轴的方向为水平 ...

  6. Codeforces Round #446 Div. 1

    B:即使看到n<=22也应该猜到这只是为了写spj.将每个数替换为恰好比他大的数即可,最大值替换为最小值.这样原序列中不包含最小值的集合显然都满足条件,并且容易发现包含最小值的集合的变化量都是最 ...

  7. Spring03-AOP

    一. AOP介绍 1. Aop介绍 AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编 ...

  8. Tarjan总结(缩点+割点(边)+双联通+LCA+相关模板)

    Tarjan求强连通分量 先来一波定义 强连通:有向图中A点可以到达B点,B点可以到达A点,则称为强连通 强连通分量:有向图的一个子图中,任意两个点可以相互到达,则称当前子图为图的强连通分量 强连通图 ...

  9. MT【254】值域包含值域

    已知函数$f(x)=x-\dfrac{1}{1+x},g(x)=x^2-2ax+4,$若对任意$x_1\in[0,1]$,存在$x_2\in[1,2]$,使得$f(x_1)=g(x_2)$,则实数$a ...

  10. python学习日记(基础数据类型及其方法02)

    python的变量 python中的变量不需要声明,变量载使用前必须被赋值,变量被赋值以后才会被创建. 在python中变量就是变量,没有数据类型.我们所说的类型是变量所指向内存中的对象的类型. py ...