[扩展KMP][HDU3613][Best Reward]
来源:互联网 发布:时间碎片交友软件 编辑:程序博客网 时间:2024/05/22 15:50
题意:
将一段字符串 分割成两个串
如果分割后的串为回文串,则该串的价值为所有字符的权值之和(字符的权值可能为负数),否则为0。
问如何分割,使得两个串权值之和最大
思路:
首先了解扩展kmp
扩展KMP:给出模板串A和子串B,长度分别为lenA和lenB,要求在线性时间内,对于每个A[i](0<=i<=lenA-1),求出A[i..lenA-1]与B的最长公共前缀长度,记为ex[i](或者说,ex[i]为满足A[i..i+z-1]==B[0..z-1]的最大的z值)。
根据上一篇文章我们可知,判断是否为回文串是复杂度的瓶颈,在这里我们可以用扩展KMP来解决。
分析:将原串s1反转得到s2,然后进行s1,s2扩展KMP匹配,得到extend,对于s1的前i个字符如果和s2的后i个字符相等即extend[len-i] == i则前i个字符为回文串,判断后len-i个字符是否是回文串用s2,s1进行扩展KMP即可
代码//非我写的
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<queue>#include<algorithm>#include<map>#include<iomanip>#define INF 99999999using namespace std;const int MAX=500000+10;char s1[MAX],s2[MAX];int next[MAX],extend1[MAX],extend2[MAX];int sum[MAX],val[27];void get_next(char *a,int len){ int k=0,i=1; next[0]=len;//可有可无,因为用不上 while(k+1<len && a[k] == a[k+1])++k; next[1]=k;//这里预先算好next[1]是因为不能k=0,否则next[i-k]=next[i]不是已算好的 k=1; while(++i<len){//和EKMP的过程一样 int maxr=k+next[k]-1; next[i]=min(next[i-k],max(maxr-i+1,0));//这里是扩展KMP的精髓,即算法核心思想就是这 while(i+next[i]<len && a[next[i]] == a[i+next[i]])++next[i]; if(i+next[i]>k+next[k])k=i; }}void EKMP(char *a,char *b,int *extend,int len){ get_next(a,len); int k=0,i=0; while(k<len && a[k] == b[k])++k; extend[0]=k; k=0; while(++i<len){ int maxr=k+extend[k]-1; extend[i]=min(next[i-k],max(maxr-i+1,0));//next[i-k]是a与b从i开始的可能已经匹配的长度 while(i+extend[i]<len && a[extend[i]] == b[i+extend[i]])++extend[i];//这里是扩展KMP的精髓,即算法核心思想就是这 if(i+extend[i]>k+extend[k])k=i; }}int main(){ int n; cin>>n; while(n--){ for(int i=0;i<26;++i)cin>>val[i]; scanf("%s",s1); int len=strlen(s1); for(int i=1;i<=len;++i){ sum[i]=sum[i-1]+val[s1[i-1]-'a']; s2[i-1]=s1[len-i]; } EKMP(s1,s2,extend1,len); EKMP(s2,s1,extend2,len); int ans=0,temp=0; for(int i=1;i<len;++i){ if(extend1[len-i] == i)temp+=sum[i];//表示前i个字符是回文串 if(extend2[i] == len-i)temp+=sum[len]-sum[i];//表示后len-i个字符为回文串 if(temp>ans)ans=temp; temp=0; } cout<<ans<<endl; } return 0;}
0 0
- [扩展KMP][HDU3613][Best Reward]
- HDU3613 Best Reward —— 扩展KMP
- HDU3613 Best Reward(扩展KMP)
- 【KMP】 hdu3613 Best Reward
- hdu3613 Best Reward(KMP)
- HDU3613 Best Reward 3连发之扩展KMP
- HDU3613:Best Reward(拓展KMP)
- HDU3613 Best Reward 3连发之KMP
- HDU3613-----Best Reward-----用扩展KMP来判断某个串是不是回文串
- HDU3613 Best Reward
- hdu3613---Best Reward
- [Manacher][HDU3613][Best Reward]
- HDU3613 Best Reward - exkmp/Manacher
- HDU 3613Best Reward(扩展KMP解法)
- Best Reward (扩展KMP+回文串)
- hdu 3613 Best Reward 扩展kmp
- hdu 3613 Best Reward (kmp扩展)
- HDU 3613 Best Reward(扩展KMP)
- java SE复习笔记36
- Snapshotting a view that has not been rendered results in an empty snapshot. Ensure your view has be
- SQL2005四个排名函数(row_number、rank、dense_rank和ntile)的比较
- leetcode 53 Maximum Subarray
- IDLE设置主题
- [扩展KMP][HDU3613][Best Reward]
- 升级了xcode7 & ios9调微信API提示未安装微信客户端解决方案
- Android Notification的使用
- phpcms自定义字段原理介绍
- C语言指针参数陷阱
- UIFont & 测量NSString大小
- Java集合器
- 进程信号的未决状态(pending status)
- 项目4 -- 链表算法库 程序的多文件组织形式