Best Reward HDU - 3613(manacher)

Best Reward

HDU - 3613

题意:每个小写字母对应有一个价值,给一个小写字母组成的串s,现在要把s切割成两段,如果切割后的串是回文串,那么价值就是该段所有字母的价值之和,问总价值最大多少。

用manacher找到前缀回文和后缀回文,枚举切点更新最大之即可。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int inf=0x3f3f3f3f;
 4 const int maxn=500000+10;
 5 char s[maxn<<1];
 6 int r[maxn<<1],sum[maxn],val[27];
 7 int per[maxn],pos[maxn];//per标记前i个字符为回文串,pos标记后i个字符为回文串
 8
 9 int main(){
10     int T;
11     scanf("%d",&T);
12     while(T--){
13         for(int i=0;i<26;++i)scanf("%d",&val[i]);
14         scanf("%s",s);
15         int len=strlen(s);
16         sum[0]=val[s[0]-‘a‘];
17         for(int i=1;i<len;++i) sum[i]=sum[i-1]+val[s[i]-‘a‘];
18         for(int i=len;i>=0;--i){
19             s[i+i+2]=s[i];
20             s[i+i+1]=‘#‘;
21         }
22         s[0]=‘*‘;
23         int id=0;
24         for(int i=2;i<len+len+1;++i){
25             if(r[id]+id>i) r[i]=min(r[2*id-i],r[id]+id-i);
26             else r[i]=1;
27             while(s[i-r[i]] == s[i+r[i]]) ++r[i];
28             if(id+r[id]<i+r[i]) id=i;
29             if(i-r[i]==0) per[r[i]-1]=T+1;//表示前缀(前r[i]-1个字符)是回文串
30             if(i+r[i]==len+len+2) pos[r[i]-1]=T+1;//表示后缀(后r[i]-1个字符)是回文串
31         }
32         int ans=0;
33         for(int i=1;i<len;++i){
34             int temp=0;
35             if(per[i]==T+1) temp+=sum[i-1];
36             if(pos[len-i]==T+1) temp+=sum[len-1]-sum[i-1];
37             ans=max(ans,temp);
38         }
39         printf("%d\n",ans);
40     }
41     return 0;
42 }

另解:扩展KMP

时间: 2024-10-12 21:18:32

Best Reward HDU - 3613(manacher)的相关文章

Best Reward HDU 3613(回文子串Manacher)

题目大意:有一个串(全部由小写字母组成),现在要把它分成两部分,如果分开后的部分是回文串就计算出来它的价值总和,如果不是回文的那么价值就是0,最多能得到的最大价值.   分析:首先的明白这个最大价值有可能是负数,比如下面: -1 -1 -1..... aaa 这样的情况不管怎么分,分出来的串都是回文串,所以得到的最大价值是 -3. 求回文串的算法使用的是Manacher算法,线性的复杂度.   代码如下: =============================================

hdu 4513(Manacher)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4513 题解:就是在Manacher判断回文串的过程中添加一条条件 Ma[i + dp[i] - 2] >= Ma[i + dp[i]]即可. #include <iostream> #include <cstring> #include <cstdio> using namespace std; const int M = 1e5 + 10; int s[M] , d

HDU 4513 吉哥系列故事——完美队形II(Manacher)

Problem Description 吉哥又想出了一个新的完美队形游戏! 假设有n个人按顺序站在他的面前,他们的身高分别是h[1], h[2] ... h[n],吉哥希望从中挑出一些人,让这些人形成一个新的队形,新的队形若满足以下三点要求,则就是新的完美队形: 1.挑出的人保持原队形的相对顺序不变,且必须都是在原队形中连续的: 2.左右对称,假设有m个人形成新的队形,则第1个人和第m个人身高相同,第2个人和第m-1个人身高相同,依此类推,当然如果m是奇数,中间那个人可以任意: 3.从左到中间那

hdu3294Girls&#39; research(manacher)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3294 题目不难,感觉输出比较麻烦. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int maxn=2000010; 6 char s[maxn<<1]; 7 int r[maxn<<1]; 8 char ans[

hdu 1874(Dijkstra )

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1874 畅通工程续 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 27692    Accepted Submission(s): 10019 Problem Description 某省自从实行了很多年的畅通工程计划后,终于修建了很多路.不过路

O(n)回文子串(Manacher)算法

O(n)回文子串(Manacher)算法 资料来源网络 参见:http://www.felix021.com/blog/read.php?2040 问题描述: 输入一个字符串,求出其中最大的回文子串.子串的含义是:在原串中连续出现的字符串片段.回文的含义是:正着看和倒着看相同,如abba和yyxyy. 解析: 这里介绍O(n)回文子串(Manacher)算法 算法基本要点:首 先用一个非常巧妙的方式,将所有可能的奇数/偶数长度的回文子串都转换成了奇数长度:在每个字符的两边都插入一个特殊的符号.比

hdu 4194(模拟)

符合三者之一的则不满足规定,求不满足规定的个数.直接模拟. 1.被同一个人审查多次 2.被和自己同一组织的审查 3.被审查次数不等于k 代码如下: 1 /************************************************** 2 * Author : xiaohao Z 3 * Blog : http://www.cnblogs.com/shu-xiaohao/ 4 * Last modified : 2014-06-28 17:36 5 * Filename :

hdu 4196(数论)

题意:问小于n的数的乘积能拼成的最大平方数是多少? 思路:给n!做质数分解在除去指数为奇数的那些质数,由于题目中需要模运算所以不能直接除,必须乘上摸逆. 代码如下: 1 /************************************************** 2 * Author : xiaohao Z 3 * Blog : http://www.cnblogs.com/shu-xiaohao/ 4 * Last modified : 2014-06-28 15:26 5 * Fi

Hdu 1402 (FFT)

题目链接 A * B Problem Plus Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 12490    Accepted Submission(s): 2206 Problem Description Calculate A * B. Input Each line will contain two integers A and