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 [题目大意] 一个字符串的价值定义为,当它是一个回文串的时候,价值为每个字符的价值的和,如果 ...
随机推荐
- Redis集群搭建与简单使用【转】
Redis集群搭建与简单使用 安装环境与版本 用两台虚拟机模拟6个节点,一台机器3个节点,创建出3 master.3 salve 环境. redis 采用 redis-3.2.4 版本. 两台虚拟机都 ...
- Flutter 基础组件:图片和Icon
前言 Flutter中,可以通过Image组件来加载并显示图片,Image的数据源可以是asset.文件.内存以及网络. ImageProvider 是一个抽象类,主要定义了图片数据获取的接口load ...
- APPIUM-Android自动化元素定位方式
一.常用元素定位方法 appium从selenium中继承了所有的元素定位方法, 并且增加了一些自己的元素定位方式,下方截图分别为selenium和MobileBy包源码: 但是从继承selenium ...
- 【Python】部署上手App后端服务器 - Linux环境搭建安装Python、Tornado、SQLAlchemy
基于阿里云服务器端环境搭建 文章目录 基于阿里云服务器端环境搭建 配置开发环境 安装 Python 3.8.2 安装 Tornado 安装 MySQL 安装 mysqlclient 安装 SQLAlc ...
- 获取网页url中的参数
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 扩展:Flash消息
扩展:Flash消息 flash存值之后只能取一次 from flask import Flask,render_template,flash,get_flashed_messages,session ...
- Py-re正则模块,log模块,config模块,哈希加密
9.re正则表达式模块,用于字符串的模糊匹配 元字符: 第一:点为通配符 用.表示匹配除了换行符以外的所有字符 import re res=re.findall('a..x','adsxwassxdd ...
- (02)-Python3之--列表(list)操作
1.定义 列表的关键字:list 列表以[]括起来,数据之间用 , 隔开.列表当中的数据,可以是任意类型.数值是可以重复的. 列表元素是 可变的,顺序是 有序的. 例如: b = ["萝卜& ...
- TCMalloc源码学习(二)
替换libc中的malloc free 不同平台替换方式不同. 基于unix的系统上的glibc,使用了weak alias的方式替换.具体来说是因为这些入口函数都被定义成了weak symbols, ...
- JS从后台获取数据,前台动态添加tr标签中的td标签
功能描述: 要求从后台查询该省份的所有城市,然后动态的再前台固定的tr标签中添加相应的td标签来展示城市基本信息: 文章目录 #一.前台jsp及js源码 jsp:在固定的tr标签中添加一个id,通过j ...