题目来源: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. 手把手教你安装QT集成开发环境(操作系统为ubuntu10.04)

    在安装QT集成开发工具包之前需要先安装build-essential和libncurses5-dev这两个开发工具和库,libncurses5-dev库是一个在Linux/Unix下广泛应用的图形函数 ...

  2. on、where、having的区别(转载)

    on.where.having的区别 on.where.having这三个都可以加条件的子句中,on是最先执行,where次之,having最后.有时候如果这先后顺序不影响中间结果的话,那最终结果是相 ...

  3. Android SurfaceView实战 打造抽奖转盘

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/41722441 ,本文出自:[张鸿洋的博客] 1.概述 今天给大家带来Surfac ...

  4. CSU1664: 防水堤坝

    Description 在太平洋的一个小岛上,岛民想要建立一个环岛的堤坝,我们能够将小岛简化为一个二维平面,你须要使用K条边(这些边要么是水平或者垂直长度为1的边,要么是45度倾斜的长度为√2的边)围 ...

  5. Java ArrayList add(int index, E element) example

    Simple add() method is used for adding an element at the end of the list however there is another va ...

  6. 我是小白之<%%>用法

    下面知识都是摘录自网络 <%=   %>输出,等价于Response.Write()<%%>  写代码<%-- --%>注释. <% %>跟其它serv ...

  7. unix命令: ifconfig

    ifconfig 命令被用来: 1.为一个网卡分配一个IP地址 2.设置本地环路界面 3.分配一个子网掩码(可选) HP-UX: # /usr/sbin/ifconfig lan0 lan0: fla ...

  8. python 获取当前日期 星期

    from datetime import datetime d =datetime.today()     #获取当前日期时间 d.isoweekday()           #获取时间周几

  9. c# 使用OracleParameter,同时使用replace函数

    也算不上是手误吧,这个问题竟然困扰了我那么多天,就是更新代码的时候,使用replace,但是oracle在.net下竟然是不支持汉字,所谓使用类似update x set y='m' where y= ...

  10. Swift - 继承UIView实现自定义可视化组件(附记分牌样例)

    在iOS开发中,如果创建一个自定义的组件通常可以通过继承UIView来实现.下面以一个记分牌组件为例,演示了组件的创建和使用,以及枚举.协议等相关知识的学习. 效果图如下:    组件代码:Score ...