hdu3613之KMP应用-程序员宅基地

技术标签: KMP  

Best Reward

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 336    Accepted Submission(s): 131


Problem Description
After an uphill battle, General Li won a great victory. Now the head of state decide to reward him with honor and treasures for his great exploit. 

One of these treasures is a necklace made up of 26 different kinds of gemstones, and the length of the necklace is n. (That is to say: n gemstones are stringed together to constitute this necklace, and each of these gemstones belongs to only one of the 26 kinds.) 

In accordance with the classical view, a necklace is valuable if and only if it is a palindrome - the necklace looks the same in either direction. However, the necklace we mentioned above may not a palindrome at the beginning. So the head of state decide to cut the necklace into two part, and then give both of them to General Li. 

All gemstones of the same kind has the same value (may be positive or negative because of their quality - some kinds are beautiful while some others may looks just like normal stones). A necklace that is palindrom has value equal to the sum of its gemstones' value. while a necklace that is not palindrom has value zero. 

Now the problem is: how to cut the given necklace so that the sum of the two necklaces's value is greatest. Output this value. 

 

Input
The first line of input is a single integer T (1 ≤ T ≤ 10) - the number of test cases. The description of these test cases follows. 

For each test case, the first line is 26 integers: v 1, v 2, ..., v 26 (-100 ≤ v i ≤ 100, 1 ≤ i ≤ 26), represent the value of gemstones of each kind. 

The second line of each test case is a string made up of charactor 'a' to 'z'. representing the necklace. Different charactor representing different kinds of gemstones, and the value of 'a' is v 1, the value of 'b' is v 2, ..., and so on. The length of the string is no more than 500000. 

 

Output
Output a single Integer: the maximum value General Li can get from the necklace.
 

Sample Input
  
  
   
2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 aba 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 acacac
 

Sample Output
  
  
   
1 6

首先输入n表示有n个测试,接着下一行有26个数分别表示a,b,c....z的价值,然后输入一行字符串,求将该字符串二分后的最大价值,二分后的字串如果是回文串则价值为字符价值之和,否则价值为0

另一种EKMP做法:http://blog.csdn.net/xingyeyongheng/article/details/9386235

另一种manacher做法:http://blog.csdn.net/xingyeyongheng/article/details/9386313

同种思路两种写法:

第一种(效率更高):

/*
思路:本题难度在于如何将原串二分后判断前缀是否是回文和后缀是否是回文串
则可以将原串反转得s2,然后用原串s1去匹配s2,最终s1匹配到的位置就是s1的最大前缀回文串
同理用s2去匹配s1得到s2的最大前缀回文串,即s1得最大后悔回文串
然后根据next[k]的特性,next[k]跳转到的位置就是下一个前缀回文串(0~k和x~len相同,而x~len又是0~k反转得到的,所以0~k是回文串)
直到k=0,将所有前缀回文串和后缀回文串标记,然后对原串线性扫描求出最大值即可 
*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<queue>
#include<algorithm>
#include<map>
#include<iomanip>
#define INF 99999999
using namespace std;

const int MAX=500000+10;
char s1[MAX],s2[MAX];
int next[MAX],sum[MAX],val[27];
int per[MAX],pos[MAX];//用来标记前缀回文串和后缀回文串

void get_next(char *a,int len){
	int i=-1,j=0;
	next[0]=-1;
	while(j<len){
		if(i == -1 || a[i] == a[j])next[++j]=++i;
		else i=next[i];
	}
}

int KMP(char *a,char *b,int len){
	int i=0,j=0;
	while(i<len && j<len){
		if(i == -1 || a[i] == b[j])++i,++j;
		else i=next[i];
	}
	return i;
}

int main(){
	int n,k;
	cin>>n;
	while(n--){
		for(int i=0;i<27;++i)scanf("%d",&val[i]);
		scanf("%s",s1);
		int len=strlen(s1);
		for(int i=0;i<len;++i)s2[i]=s1[len-1-i],sum[i+1]=sum[i]+val[s1[i]-'a'];
		get_next(s1,len);
		k=KMP(s1,s2,len);//求s1最大前缀回文串位置
		while(k)per[k]=n+1,k=next[k];//标记所有前缀回文串 
		get_next(s2,len);
		k=KMP(s2,s1,len);//求s1最大后缀回文串位置 
		while(k)pos[k]=n+1,k=next[k];//标记所有后缀回文串 
		int ans=-INF,num=0;
		for(int i=1;i<len;++i){
			if(per[i] == n+1)num+=sum[i];
			if(pos[len-i] == n+1)num+=sum[len]-sum[i];
			if(num>ans)ans=num;
			num=0;
		}
		cout<<ans<<endl;
	}
} 
第二种:

思路:将原串 + 一个字符(比如'#') + 原串反转后的串  得到新串s,对s求next,则next[len]为原串的回文前缀,一直next[len]则可得到所有回文前缀,然后求原串后缀,最后求结果

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<queue>
#include<algorithm>
#include<map>
#include<iomanip>
#define INF 99999999
using namespace std;

const int MAX=500000+10;
char s[MAX*2];
int next[MAX*2],sum[MAX],val[27];
int pre[MAX],pos[MAX];//标记原串中的回文前缀和回文后缀 

void get_next(char *a,int len){
	int i=-1,j=0;
	next[0]=-1;
	while(j<len){
		if(i == -1 || a[i] == a[j])next[++j]=++i;
		else i=next[i];
	}
	return;
}

int main(){
	int n;
	cin>>n;
	while(n--){
		for(int i=0;i<26;++i)scanf("%d",&val[i]);
		scanf("%s",s);
		int len=strlen(s),k=len,temp=len;
		for(int i=1;i<=len;++i)sum[i]=sum[i-1]+val[s[i-1]-'a'];
		s[len]='#';//中间用一个字符隔开则next[len]就一定在#前面,即寻找到的回文前缀一定是原串的回文前缀 
		while(k)s[++len]=s[--k];//将原串反转连接在原串后面 
		s[++len]='\0';
		get_next(s,len);
		k=len;
		while(next[k])pre[next[k]]=n+1,k=next[k];//标记前next[len]个字符是回文串,即标记回文前缀 
		for(int i=0;i<temp;++i){//前后两部分字串交换位置实现将最初原串反转连接在前面,为了求回文后缀 
			s[i]=s[i]^s[temp+1+i];
			s[temp+1+i]=s[i]^s[temp+1+i];
			s[i]=s[i]^s[temp+1+i];
		}
		get_next(s,len);
		k=len;
		while(next[k])pos[next[k]]=n+1,k=next[k];//标记前next[len]是回文串,即标记回文后缀
		int ans=-INF,num=0;
		for(int i=1;i<temp;++i){//求最大值 
			if(pre[i] == n+1)num+=sum[i];
			if(pos[temp-i] == n+1)num+=sum[temp]-sum[i];
			if(num>ans)ans=num;
			num=0;
		}
		cout<<ans<<endl;
	}
	return 0;
}


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xingyeyongheng/article/details/9292449

智能推荐

基于SSM的网上书城管理系统+00210(免费领源码)可做计算机毕业设计JAVA、PHP、爬虫、APP、小程序、C#、C++、python、数据可视化、大数据、全套文案_网上书城商品管理系统-程序员宅基地

文章浏览阅读951次,点赞12次,收藏21次。本选题则旨在通过标签分类管理等方式,实现首页、网站管理(轮播图、通知公告)、人员管理(管理员、普通用户)、内容管理(交流论坛、论坛分类、文章资讯、文章分类)、购物管理(图书商城、分类列表、订单列表)、模块管理(用户反馈)、个人管理(个人信息,修改密码)等信息管理功能,从而达到对网上书城管理系统信息的高效管理。_网上书城商品管理系统

redis及redis-desktop-manager的下载及安装_redisdesktopmanager下载 32位-程序员宅基地

文章浏览阅读3.3k次。一、下载安装redis链接:https://pan.baidu.com/s/1ax2mMEfT5JPpqPv1YV5XNA 提取码:zfu0官网地址:Releases · tporadowski/redis · GitHubredis-desktop-manager链接:https://pan.baidu.com/s/1BxfcOdTCUXvJTycp_ET6Qw 提取码:cvbk二、启动redis解压后双击redis-server.exe启动出现如下图小黑板表示启动成功了_redisdesktopmanager下载 32位

B站狂神说--ElasticSearch笔记_狂神elasticsearch笔记-程序员宅基地

文章浏览阅读1.6k次。课程(免费)网址:https://www.bilibili.com/video/BV17a4y1x7zq?spm_id_from=333.999.0.0笔记来源:https://www.kuangstudy.com/bbs/1442736481234939905#header30ps:狂神很良心,yyds!一、ElasticSearch概述1.ElasticSearchElasticsearch是一个实时分布式搜索和分析引擎。 它让你以前所未有的速度处理大数据成为可能。它用于全文搜索、结构化搜_狂神elasticsearch笔记

TaskQuery查询API-程序员宅基地

文章浏览阅读1w次。1、TaskQuery查询API 有两种方法可以从引擎中查询数据:查询API和原生查询。查询API提供了完全类型安全的API。 你可以为自己的查询条件添加很多条件 (所以条件都以AND组合)和精确的排序条件。下面的代码展示了一个例子:Java代码 List tasks = taskService.createTaskQuery() _taskquery

windows搭建Rust开发环境报错error: linking with `x86_64-w64-mingw32-gcc` failed: exit code: 1-程序员宅基地

文章浏览阅读1.2k次,点赞21次,收藏25次。Rust环境配置,报错_error: linking with `x86_64-w64-mingw32-gcc` failed: exit code

Docker核心技术(一)_docker技术核心-程序员宅基地

文章浏览阅读1.1k次。Docker核心技术1.Docker的简介1)前提知识和课程定位2)什么是Docker3)Docker能干什么?(1)之前的虚拟机技术(2)容器虚拟化技术(3)开发/运维(DevOps)(4)企业级4)去哪下?Docker的安装前提说明CentOS Docker安装前提条件查看自己的内核Docker的基本组成Docker的安装步骤1)CentOS6.8的Docker的安装2)CentOS7安装Do..._docker技术核心

随便推点

getshell_getsheell-程序员宅基地

文章浏览阅读735次。上传题:一共三个过滤请求头部的 Content-Type文件后缀请求数据的Content-Type这里是黑名单过滤来判断文件后缀,依次尝试php4,phtml,phtm,phps,php5(包括一些字母改变大小写)最终发现,php5(PHP5)可以绕过接下来,请求数据的Content-Type字段改为 image/jpeg但是一开始没注意到,上面还有一个请求头Content-..._getsheell

PL/SQL Developer查询窗口显示所有行的设置方法_plsql多个sql窗口并排显示-程序员宅基地

文章浏览阅读7.1k次。首先,点击【配置】-【首选项】然后,点击【首选项】窗口中左边栏【SQL窗口】,每页记录数选择【所有记录】就这样,查询数据较多时,不必再点击下一页按钮了,方便许多。。。 ..._plsql多个sql窗口并排显示

这 5 个前端组件库,可以让你放弃 jQuery UI_jq ui 前段-程序员宅基地

文章浏览阅读337次。本文参考文章:https://www.sitepoint.com/top-5-jquery-ui-alternatives/ 转载请注明出自:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案..._jq ui 前段

vue2 怎么用vite_Vue3之——和Vite不得不说的事-程序员宅基地

文章浏览阅读3.3k次。1.创建一个vite项目npm init vite-app cd npm installnpm run dev或者yarn create vite-app cd yarnyarn dev2.vite简介vite 是一个基于 Vue3 单文件组件的非打包开发服务器,它做到了本地快速开发启动:快速的冷启动,不需要等待打包操作;即时的热模块更新,替换性能和模块数量的解耦让更新飞起;真正的按需编译,不再等..._[vite] hmr update /src/components/common/header.vue?vue&type=style&index=0&s

ERwin根据映射文件,自动为物理模型命英文名_erwin物理模型转英文-程序员宅基地

文章浏览阅读1.1w次,点赞2次,收藏24次。在以前的帖子中说过,要整理下ERwin由逻辑模型到物理模型的映射,一直没时间,今天终于整理了,如下: 项目的建模工具,用的较多的有PD、Rose,我学生时代,就没听说过ERwin,这个工具也是进入项目组之后才了解到的。ERwin中分为逻辑模型和物理模型两种。在创建逻辑模型时,我们都是通过中文设计,这样就更直观的显示模型的作用;物理模型,是直接对数据库进行关联,对数据库进行操作,_erwin物理模型转英文

多用户同时处理同一条数据解决办法_后台 不同的用户抢占同一数据怎么处理-程序员宅基地

文章浏览阅读10w+次,点赞21次,收藏83次。事务处理(多用户同时操作一条信息时是用-并发)在c/s或多层中,如果两个用户同时打开一条记录,修改后提交会产生更新冲突; 据说办法有二:1。打开同时锁定表的记录 2。浦获错误,撤消其中一个用户的修改,但是很少见到具体实现的代码;请大家告诉具体的代码怎么写: 1。打开时如何锁定一条记录? 2。如何扑获更新错误?在delphi中调试时会报“该记录读出后已经被再次修改”,而在运行时如_后台 不同的用户抢占同一数据怎么处理