题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3613

题目大意:

题目大意就是将字符串s分成两部分子串,
若子串是回文串则需计算价值,否则价值为0,求分割字符串s能获得的最大价值。

解题思路:

用manacher算法计算出p[i],每次计算p[i]是顺便计算一下这段回文串
是否能到达边界,若能则计算出前缀或者后缀的结束位置,标记起来。//还有之前数组开1e6+5教C++是错的,改成2e6+5就对了,不觉明历。。。。

代码(复杂点的)

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=2e6+;
const int INF=0x3f3f3f3f; int len1,len2;
int p[N],sum[N],val[N],pre[N],hou[N];
char s[N],str[N]; void init(){
str[]='$';
str[]='#';
for(int i=;i<len1;i++){
str[i*+]=s[i];
str[i*+]='#';
}
len2=len1*+;
str[len2]='\0';
} void manacher(){
int id=,mx=;
for(int i=;i<len2;i++){
if(mx>i) p[i]=min(p[*id-i],mx-i);
else p[i]=;
while(str[i+p[i]]==str[i-p[i]])
p[i]++;
if(p[i]+i>mx){
id=i;
mx=p[i]+i;
}
if(i-p[i]==){
pre[p[i]+i-]=;
}
if(i+p[i]==len2){
hou[i-p[i]+]=;
}
}
} int main(){
int t;
scanf("%d",&t);
while(t--){
memset(pre,,sizeof(pre));
memset(hou,,sizeof(hou));
for(int i=;i<;i++){
scanf("%d",&val[i]);
}
scanf("%s",s);
len1=strlen(s);
init();
manacher();
for(int i=;i<len2;i++){
if(i=='#') sum[i]=sum[i-];
else sum[i]=sum[i-]+val[str[i]-'a'];
}
int ans=-INF;
//枚举分割点
for(int i=;i<len2-;i++){
int tmp=;
if(pre[i]) tmp+=sum[i];
if(hou[i]) tmp+=sum[len2-]-sum[i];
ans=max(ans,tmp);
}
printf("%d\n",ans);
}
return ;
}

简略了一点的

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=2e6+;
const int INF=0x3f3f3f3f; int len1,len2;
int p[N],sum[N],val[N];
char s[N],str[N]; void init(){
str[]='$';
str[]='#';
for(int i=;i<len1;i++){
str[i*+]=s[i];
str[i*+]='#';
}
len2=len1*+;
str[len2]='@';
} void manacher(){
int id=,mx=;
for(int i=;i<len2;i++){
if(mx>i) p[i]=min(p[*id-i],mx-i);
else p[i]=;
while(str[i+p[i]]==str[i-p[i]])
p[i]++;
if(p[i]+i>mx){
id=i;
mx=p[i]+i;
}
}
} int main(){
int t;
scanf("%d",&t);
while(t--){
for(int i=;i<;i++){
scanf("%d",&val[i]);
}
scanf("%s",s);
len1=strlen(s);
init();
manacher();
for(int i=;i<len2;i++){
if(i=='#') sum[i]=sum[i-];
else sum[i]=sum[i-]+val[str[i]-'a'];
}
int ans=-INF;
//枚举分割点
for(int i=;i<len1-;i++){
int tmp=,mid;
mid=((i+)*++)/;
if(mid-p[mid]==) tmp+=sum[(i+)*];
mid=((i+)*-+len1*+)/;
if(mid+p[mid]==len2) tmp+=sum[len2-]-sum[(i+)*-];
ans=max(tmp,ans);
}
printf("%d\n",ans);
}
return ;
}

HDU 3613 Best Reward(manacher求前、后缀回文串)的更多相关文章

  1. POJ 3376 Finding Palindromes(manacher求前后缀回文串+trie)

    题目链接:http://poj.org/problem?id=3376 题目大意:给你n个字符串,这n个字符串可以两两组合形成n*n个字符串,求这些字符串中有几个是回文串. 解题思路:思路参考了这里: ...

  2. HDU 3613 Best Reward(扩展KMP求前后缀回文串)

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

  3. Manacher算法 - 求最长回文串的利器

    求最长回文串的利器 - Manacher算法 Manacher主要是用来求某个字符串的最长回文子串. 不要被manacher这个名字吓倒了,其实manacher算法很简单,也很容易理解,程序短,时间复 ...

  4. Manacher(最长镜面回文串)

    I - O'My! Gym - 101350I Note: this is a harder version of Mirrored string I. The gorillas have recen ...

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

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

  6. hdu 3613"Best Reward"(Manacher算法)

    传送门 题意: 国王为了犒劳立下战功的大将军Li,决定奖给Li一串项链,这个项链一共包含26中珠子"a~z",每种珠子都有 相应的价值(-100~100),当某个项链可以构成回文时 ...

  7. hdu 3068 最长回文 【Manacher求最长回文子串,模板题】

    欢迎关注__Xiong的博客: http://blog.csdn.net/acmore_xiong?viewmode=list 最长回文                                 ...

  8. hdu 3068 最长回文 (Manacher算法求最长回文串)

    参考博客:Manacher算法--O(n)回文子串算法 - xuanflyer - 博客频道 - CSDN.NET 从队友那里听来的一个算法,O(N)求得每个中心延伸的回文长度.这个算法好像比较偏门, ...

  9. Manacher's Algorithm 马拉车算法(求最长回文串)

    作用:求一个字符串中的最长子串,同时还可以求所有子串的长度. 题目链接: https://vjudge.net/contest/254692#problem/B 最长回文串长度的代码: int Man ...

随机推荐

  1. iterm2切换显示屏vim乱行解决

    http://note.youdao.com/noteshare?id=5aec9d82cc3a95b6909e9966b4aa3227

  2. STL中的优先级队列priority_queue

    priority_queue(queue类似)完全以底部容器为根据,再加上二叉堆(大根堆或者小根堆)的实现原理,所以其实现非常简单,缺省情况下priority_queue以vector作为底部容器.另 ...

  3. Centos6.6下安装nginx1.6.3

    安装环境: [root@nginx ~]# cat /etc/redhat-release CentOS release 6.6 (Final) [root@nginx ~]# uname -r 2. ...

  4. python 启航

    first = 1while first<=9: sec = 1        while sec <= first:        print(  str(sec)+"*&qu ...

  5. IOS子视图超过父视图frame后,无法交互响应

    确定第一响应者 当用户触发某一事件(触摸事件或运动事件)后,UIKit会创建一个事件对象(UIEvent),该对象包含一些处理事件所需要的信息.然后事件对象被放到一个事件队列中.这些事件按照先进先出的 ...

  6. 前端路由的两种模式: hash 模式和 history 模式

    随着 ajax 的使用越来越广泛,前端的页面逻辑开始变得越来越复杂,特别是spa的兴起,前端路由系统随之开始流行. 从用户的角度看,前端路由主要实现了两个功能(使用ajax更新页面状态的情况下): 记 ...

  7. Vue入坑教程(二)——项目结构详情介绍

    之前已经介绍了关于Vue的脚手架vue-cli的安装,以及一些文件目录介绍.具体可以查看<vue 入坑教程(一)--搭建vue-cli脚手架> 下面简单说一下具体的文件介绍 (一) pac ...

  8. Typora 自定义主题 修改左右间距

    打开偏好设置,打开主题文件夹 比如要修改night主题中的间距,编辑night.css文件,修改#write样式即可. 修改其他样式类试.

  9. android onActivityResult的执行

    1.如果activity中重写了onActivityResult函数,同时添加在该activity的fragment也重写了onActivtyResult函数,那么会执行Activity的onActi ...

  10. 你都掌握了吗?jQuery 选择器大全

    在 Dom 编程中我们只能使用有限的函数根据 id 或者 TagName 获取 Dom 对象. 然而在 jQuery 中则完全不同,jQuery 提供了异常强大的选择器用来帮助我们获取页面上的对象, ...