HDU - 3613 Best Reward(manacher或拓展kmp)
传送门:HDU - 3613
题意:给出26个字母的价值,然后给你一个字符串,把它分成两个字符串,字符串是回文串才算价值,求价值最大是多少。
题解:这个题可以用马拉车,也可以用拓展kmp。
①Manacher:先记录下第i个字符的价值,然后求前缀和。然后遍历分的位置,分别判断前半段和后半段是否为回文串,是回文串的加上这段的价值(前缀和相减),更新最大价值。
1 #include<bits/stdc++.h>
2 using namespace std;
3
4 int p[1000100],val[500100];
5 char s[500100];
6 map<char,int> mp;
7
8 void Manacher(char str[])
9 {
10 memset(p,0,sizeof(p));
11 string s="$#";
12 int len=strlen(str);
13 for(int i=0;i<len;i++){
14 s+=str[i];
15 s+='#';
16 }
17 int mx=0,id=0,reslen=0,rescenter=0;
18 len=s.length();
19 for(int i=1;i<=len;i++){
20 if(mx>i) p[i]=min(p[2*id-i],mx-i);
21 else p[i]=1;
22 while(s[i+p[i]]==s[i-p[i]]) p[i]++;
23 if(mx<i+p[i]){
24 mx=i+p[i];
25 id=i;
26 }
27 }
28 }
29
30 int main()
31 {
32 int t;
33 cin>>t;
34 while(t--){
35 mp.clear();
36 for(int i=0;i<26;i++){
37 int x;
38 cin>>x;
39 mp['a'+i]=x;
40 }
41 cin>>s;
42 int len=strlen(s);
43 for(int i=0;i<len;i++){
44 if(!i) val[i]=mp[s[i]];
45 else val[i]=val[i-1]+mp[s[i]];
46 }
47 int ans=0;
48 Manacher(s);
49 for(int i=1;i<len;i++){
50 int p1=0,p2=0;
51 int x=i*2+1;
52 x=x/2+1; ///<i的串的中心位置
53 int y=(len-i)*2+1;
54 y=y/2+1;
55 y=(len*2+2)-y; ///剩下部分的中心位置
56 if(p[x]==x) p1=val[i-1];
57 if(p[y]+y==len*2+2) p2=val[len-1]-val[i-1];
58 ans=max(ans,p1+p2);
59 }
60 cout<<ans<<endl;
61 }
62 return 0;
63 }
②拓展kmp:用原串和反串进行比较,第一次原串做主串,第二次反串做主串。遍历分的位置,如果ex1[i]+i==len,那么说明s中的0~i-1为回文串,如果ex2[len-i]==i,说明s中的i~len-1为回文串,是回文串的价值加上,记录最大的价值。
1 #include<bits/stdc++.h>
2 using namespace std;
3
4 ///next[i]: T[i]到T[m - 1]与T(模式串)的最长相同前缀长度;
5 ///extend[i]: S[i]到S[n - 1](原串)与T的最长相同前缀长度。
6
7 const int maxn=500100; //字符串长度最大值
8 int nt[maxn],ex1[maxn],ex2[maxn]; //ex数组即为extend数组
9 int val[30];
10
11 //预处理计算next数组
12 void GETNEXT(char *str)
13 {
14 int i=0,j,po,len=strlen(str);
15 nt[0]=len; //初始化nt[0]
16 while(str[i]==str[i+1]&&i+1<len) i++; //计算nt[1]
17 nt[1]=i;
18 po=1; //初始化po的位置
19 for(i=2;i<len;i++){
20 if(nt[i-po]+i<nt[po]+po) nt[i]=nt[i-po]; //第一种情况,可以直接得到nt[i]的值
21 else{ //第二种情况,要继续匹配才能得到nt[i]的值
22 j=nt[po]+po-i;
23 if(j<0) j=0; //如果i>po+nt[po],则要从头开始匹配
24 while(i+j<len&&str[j]==str[j+i]) j++; //计算nt[i]
25 nt[i]=j;
26 po=i; //更新po的位置
27 }
28 }
29 }
30
31 //计算extend数组
32 void EXKMP(char *s1,char *s2,int *ex) ///s1的后缀和s2的前缀匹配
33 {
34 int i=0,j,po,len=strlen(s1),l2=strlen(s2);
35 GETNEXT(s2); //计算子串的next数组
36 while(s1[i]==s2[i]&&i<l2&&i<len) i++; //计算ex[0]
37 ex[0]=i;
38 po=0; //初始化po的位置
39 for(i=1;i<len;i++){
40 if(nt[i-po]+i<ex[po]+po) ex[i]=nt[i-po]; //第一种情况,直接可以得到ex[i]的值
41 else{ //第二种情况,要继续匹配才能得到ex[i]的值
42 j=ex[po]+po-i;
43 if(j<0) j=0; //如果i>ex[po]+po则要从头开始匹配
44 while(i+j<len&&j<l2&&s1[j+i]==s2[j]) j++; //计算ex[i]
45 ex[i]=j;
46 po=i; //更新po的位置
47 }
48 }
49 }
50
51 char s[maxn];
52 int sum[maxn];
53 char p[maxn];
54
55 int main()
56 {
57 int t;
58 cin>>t;
59 while(t--){
60 for(int i=0;i<26;i++)
61 cin>>val[i];
62 cin>>s;
63 int len=strlen(s);
64 for(int i=0;i<len;i++)
65 if(!i) sum[i]=val[s[i]-'a'];
66 else sum[i]=val[s[i]-'a']+sum[i-1];
67 strcpy(p,s);
68 reverse(p,p+len);
69 EXKMP(s,p,ex1); //s做主串
70 EXKMP(p,s,ex2); //p做主串
71 int ans=0;
72 for(int i=1;i<len;i++){
73 int ans1=0,ans2=0;
74 if(ex1[i]+i==len) ans1=sum[len-1]-sum[i-1]; //s中的0~i-1;
75 if(ex2[len-i]==i) ans2=sum[i-1]; //s中的i~len-1
76 ans=max(ans,ans1+ans2);
77 }
78 cout<<ans<<endl;
79 }
80 return 0;
81 }
HDU - 3613 Best Reward(manacher或拓展kmp)的更多相关文章
- hdu 3613"Best Reward"(Manacher算法)
传送门 题意: 国王为了犒劳立下战功的大将军Li,决定奖给Li一串项链,这个项链一共包含26中珠子"a~z",每种珠子都有 相应的价值(-100~100),当某个项链可以构成回文时 ...
- HDU 3613 Best Reward 正反两次扩展KMP
题目来源:HDU 3613 Best Reward 题意:每一个字母相应一个权值 将给你的字符串分成两部分 假设一部分是回文 这部分的值就是每一个字母的权值之和 求一种分法使得2部分的和最大 思路:考 ...
- HDU 3613 Best Reward ( 拓展KMP求回文串 || Manacher )
题意 : 给个字符串S,要把S分成两段T1,T2,每个字母都有一个对应的价值,如果T1,T2是回文串,那么他们就会有一个价值,这个价值是这个串的所有字母价值之和,如果不是回文串,那么这串价值就为0.问 ...
- HDU 3613 Best Reward(拓展KMP算法求解)
题目链接: https://cn.vjudge.net/problem/HDU-3613 After an uphill battle, General Li won a great victory. ...
- HDU - 4300 Clairewd’s message (拓展kmp)
HDU - 4300 题意:这个题目好难读懂,,先给你一个字母的转换表,然后给你一个字符串密文+明文,密文一定是全的,但明文不一定是全的,求最短的密文和解密后的明文: 题解:由于密文一定是全的,所以他 ...
- 扩展KMP --- HDU 3613 Best Reward
Best Reward Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=3613 Mean: 给你一个字符串,每个字符都有一个权 ...
- HDU 3613 Best Reward(扩展KMP求前后缀回文串)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3613 题目大意: 大意就是将字符串s分成两部分子串,若子串是回文串则需计算价值,否则价值为0,求分割 ...
- HDU 3613 Best Reward(manacher求前、后缀回文串)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3613 题目大意: 题目大意就是将字符串s分成两部分子串,若子串是回文串则需计算价值,否则价值为0,求分 ...
- HDU 3613 Best Reward(扩展KMP)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3613 [题目大意] 一个字符串的价值定义为,当它是一个回文串的时候,价值为每个字符的价值的和,如果 ...
随机推荐
- Ocelot一个优秀的.NET API网关框架
1 什么是Ocelot? Ocelot是一个用.NET Core实现并且开源的API网关,它功能强大,包括了:路由.请求聚合.服务发现.认证.鉴权.限流熔断.并内置了负载均衡器与Service Fab ...
- Harbor镜像删除回收?只看这篇
最近,公司的技术平台,运维的破事儿颇多.Jira无法访问,ES堆内存不足,Jenkins频繁不工作..等等等,让我这个刚入门的小兵抓心脑肝,夜不能寐,关键时刻方恨经验薄弱呀!!一波未平,一波又起,这不 ...
- 【MySQL 高级】索引优化分析
MySQL高级 索引优化分析 SQL 的效率问题 出现性能下降,SQL 执行慢,执行时间长,等待时间长等情况,可能的原因有: 查询语句写的不好 索引失效 单值索引:在 user 表中给 name 属性 ...
- [从源码学设计]蚂蚁金服SOFARegistry之续约和驱逐
[从源码学设计]蚂蚁金服SOFARegistry之续约和驱逐 目录 [从源码学设计]蚂蚁金服SOFARegistry之续约和驱逐 0x00 摘要 0x01 业务范畴 1.1 失效剔除 1.2 服务续约 ...
- 【Java】一个简单的Java应用程序
简单记录,Java 核心技术卷I 基础知识(原书第10 版) 一个简单的Java应用程序"Hello, World!" Hello, World! Goodbye,World! 一 ...
- 基于FPGA的光口通信开发案例|基于Kintex-7 FPGA SFP+光口的10G UDP网络通信开发案例
前言 自著名华人物理学家高锟先生提出"光传输理论",实用化的光纤传输产品始于1976年,经历了PDH→SDH→DWDM→ASON→MSTP的发展历程.本世纪初期,ASON/OADM ...
- mysql 1449 : The user specified as a definer ('usertest'@'%') does not exist 解决方法 (grant 授予权限)
从服务器上迁移数据库到本地localhost 执行 函数 时报错, mysql 1449 : The user specified as a definer ('usertest'@'%') do ...
- [Usaco2008 Mar]Cow Travelling游荡的奶牛
题目描述 奶牛们在被划分成N行M列(2 <= N <= 100; 2 <= M <= 100)的草地上游走,试图找到整块草地中最美味的牧草.Farmer John在某个时刻看见 ...
- 邮箱发送API .Net
调用QQ邮箱发送邮件接口,完成QQ邮箱发送邮件.步骤如下: 1.开启POP3/SMTP服务 2.点过之后会让你验证一下密保或者发送一条短信 3.验证过后会弹出一个开启POP3/SMTP服务的授权码,这 ...
- mybatis缓存源码分析之浅谈缓存设计
本文是关于mybatis缓存模块设计的读后感,关于缓存的思考,关于mybatis的缓存源码详细分析在另一篇文章:https://www.cnblogs.com/gmt-hao/p/12448896.h ...