题目来源:HDU 3613 Best Reward

题意:每一个字母相应一个权值 将给你的字符串分成两部分 假设一部分是回文 这部分的值就是每一个字母的权值之和 求一种分法使得2部分的和最大

思路:考虑扩展KMP 输出a串 得到a的反串b 求出f[0]和f[1] 和 extend[0]和extend[1] 正反求2次

枚举位置i 分成2部分0到i-1 和i到n-1 由于分成的2部分必须组成原字符串 就是不能多也不能少

那么推断i+extend[i]是否等于n 等于说明i到n-1这个部分是回文串 sum1 为这部分的值 假设这部分不是回文sum1 = 0

推断0到i-1是不是回文 将a和b翻转 那么就和推断i到n-1是一样的  所以上面正反求了2次 sum2 为这部分的值 假设这部分不是回文sum2 = 0

去sum1+sum2的最大值 另外字符串的值能够递推求得

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 500010;
int f[2][maxn], ex[2][maxn];
char a[maxn], b[maxn];
int id[26], dp[2][maxn];
void getFail(char* s, int id, int n)
{
int k = 1, p = 0;
while(p+1 < n && s[p] == s[p+1])
p++;
f[id][0] = n;
f[id][1] = p;
for(int i = 2; i < n; i++)
{
int l = f[id][i-k];
int p = f[id][k]+k-1;
if(i+l-1 < p)
f[id][i] = l;
else
{
int j = p-i+1;
if(j < 0)
j = 0;
while(i+j < n && s[i+j] == s[j])
j++;
f[id][i] = j;
k = i;
}
}
} void getEx(char* s, char* t, int id, int n)
{
int k = 0, p = 0;
while(p < n && s[p] == t[p])
p++;
ex[id][0] = p;
for(int i = 1; i < n; i++)
{
int l = f[id^1][i-k];
int p = ex[id][k]+k-1;
if(i+l-1 < p)
ex[id][i] = l;
else
{
int j = p-i+1;
if(j < 0)
j = 0;
while(i+j < n && s[i+j] == t[j])
j++;
ex[id][i] = j;
k = i;
}
}
} int main()
{
int T;
scanf("%d", &T);
while(T--)
{
for(int i = 0; i < 26; i++)
scanf("%d", &id[i]);
scanf("%s", a);
int n = strlen(a); for(int i = 0; i < n; i++)
{
b[i] = a[n-i-1];
if(i)
dp[0][i] = id[a[i]-'a'] + dp[0][i-1];
else
dp[0][i] = id[a[i]-'a'];
}
for(int i = 0; i < n; i++)
{
if(i)
dp[1][i] = dp[1][i-1] + id[b[i]-'a'];
else
dp[1][i] = id[b[i]-'a'];
}
getFail(a, 0, n);
getFail(b, 1, n);
getEx(a, b, 0, n);
getEx(b, a, 1, n);
int ans = 0;
for(int i = 1; i < n; i++)
{
int sum1 = 0, sum2 = 0;
if(i+ex[0][i] == n)
sum1 = dp[1][ex[0][i]-1];
int j = n-i;
if(j+ex[1][j] == n)
sum2 = dp[0][ex[1][j]-1];
ans = max(ans, sum1+sum2);
//printf("%d %d\n", ex[0][i], ex[1][i]);
}
printf("%d\n", ans);
}
return 0;
}

HDU 3613 Best Reward 正反两次扩展KMP的更多相关文章

  1. HDU - 3613 Best Reward(manacher或拓展kmp)

    传送门:HDU - 3613 题意:给出26个字母的价值,然后给你一个字符串,把它分成两个字符串,字符串是回文串才算价值,求价值最大是多少. 题解:这个题可以用马拉车,也可以用拓展kmp. ①Mana ...

  2. 扩展KMP --- HDU 3613 Best Reward

    Best Reward Problem's Link:   http://acm.hdu.edu.cn/showproblem.php?pid=3613 Mean: 给你一个字符串,每个字符都有一个权 ...

  3. HDU 3613 Best Reward(扩展KMP求前后缀回文串)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3613 题目大意: 大意就是将字符串s分成两部分子串,若子串是回文串则需计算价值,否则价值为0,求分割 ...

  4. hdu 3613"Best Reward"(Manacher算法)

    传送门 题意: 国王为了犒劳立下战功的大将军Li,决定奖给Li一串项链,这个项链一共包含26中珠子"a~z",每种珠子都有 相应的价值(-100~100),当某个项链可以构成回文时 ...

  5. HDU 3613 Best Reward(扩展KMP)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3613 [题目大意] 一个字符串的价值定义为,当它是一个回文串的时候,价值为每个字符的价值的和,如果 ...

  6. HDU 3613 Best Reward(manacher求前、后缀回文串)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3613 题目大意: 题目大意就是将字符串s分成两部分子串,若子串是回文串则需计算价值,否则价值为0,求分 ...

  7. HDU 3613 Best Reward(KMP算法求解一个串的前、后缀回文串标记数组)

    题目链接: https://cn.vjudge.net/problem/HDU-3613 After an uphill battle, General Li won a great victory. ...

  8. hdu 3613 Best Reward

    After an uphill battle, General Li won a great victory. Now the head of state decide to reward him w ...

  9. hdu 3613 Best Reward (manachar算法)

    Best Reward Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Prob ...

随机推荐

  1. Windows Phone 9再见了!

    因为需要准备注册电气工程师考试,因此Windows Phone 8初学者教程的翻译只能就此打住了,在考完后,也许就是Windows Phone 9发布的时候还会回来! Bye bye!

  2. Ajax Post提交事例及SpringMVC注解@RequestMapping取不到参数值解决办法

    var xmlHttp; //定义变量,用来创建xmlHttp对象 function ajaxfunction(url,onreadystatechangMethod,param){ // 创建xml ...

  3. 哈,又一款超级简单的队列(MQ)实现方案来了~

    开源的消息队列已经很多了,但大部分很重,实际环境下,很多可能只是使用到了一点功能而已,杀鸡使用牛刀,着实有些浪费了.很多时候,我们只想要一片绿叶,但它们给了我们整个的春天,很难消化.本着DIR精神, ...

  4. VC 对话框背景颜色、控件颜色

    系统环境:Windows 7软件环境:Visual C++ 2008 SP1本次目的:为对话框设置背景颜色.控件颜色 既然MFC对话框不好开发,那么现在我们来开始美化我们的对话框.为对话框设置背景颜色 ...

  5. 获取DOM元素位置和尺寸大小

    JavaScript获取DOM元素位置和尺寸大小 在一些复杂的页面中经常会用JavaScript处理一些DOM元素的动态效果,这种时候我们经常会用到一些元素位置和尺寸的计算,浏览器兼容性问题也是不可忽 ...

  6. 对于面向对象的理解(JAVA)

    JAVA 是一门优美的面向对象的语言.那问题就来了什么是对象,这个问题有一个简单的诠释 “万物皆对象”.那么在面向对象编程中对象是类的一个实例,那么什么是类呢?类是一组相似对象的共有特征的抽象.类有什 ...

  7. (升级版)Spark从入门到精通(Scala编程、案例实战、高级特性、Spark内核源码剖析、Hadoop高端)

    本课程主要讲解目前大数据领域最热门.最火爆.最有前景的技术——Spark.在本课程中,会从浅入深,基于大量案例实战,深度剖析和讲解Spark,并且会包含完全从企业真实复杂业务需求中抽取出的案例实战.课 ...

  8. 从注册流程 分析如何安全退出多个Activity 多种方式(附DEMO)

    前言   由于一个同学问到我如何按照一个流程走好之后回到首页,我以前看到过4个解决方案,后来发现有做个记录和总结的必要,就写了这篇博文.(之前看小强也写过一篇,这里通过自身的分析完整的总结一下以下6种 ...

  9. 如果一个Object对象可能是数组那么如何对其进行迭代

    需求:一个方法传入的参数是Object类型(假设对象为“items”,使用Object类型也是为了使用多态而增加方法复用性),但已知这个Object对象可能是基本类型数组,也可能是对象数组,如何将这个 ...

  10. iot表输出按主键列排序,heap表不是

    <pre name="code" class="html"> create table t1 (id char(10) primary key,a1 ...