递推预处理 + Manacher
链接:https://www.nowcoder.com/acm/contest/131/D
来源:牛客网
删除字符串的第一个字母。
删除字符串的最后一个字母。
在字符串的头部添加任意一个你想要的字母。
在字符串的尾部添加任意一个你想要的字母。
删除一个第 i 种英文字母需要的花费是 Ai,添加一个第 i 种英文字母的花费是 Bi。
请问将字符串 S 变成回文串需要的最小花费是多少?
输入描述:
第一行输入一个字符串 S。
接下来 26 行,每行输入两个正整数 A
i
和 B
i
,表示删除一个第 i 种字符所需的花费以及添加一个第 i 种字符所需的花费。
1≤ |S| ≤ 10
5
且字符串 S 中只包含小写英文字母 1≤ A
i
,B
i
≤ 109.
输出描述:
输出一个正整数,表示把字符串 S 变成一个回文串的最小花费。
输入
jelly
1000 1100
350 700
200 800
2000 2000
2000 432
2000 2000
2000 2000
2000 2000
2000 2000
20 2000
2000 2000
350 35
200 800
2000 2000
2000 2000
2000 2000
2000 2000
2000 2000
2000 2000
2000 2000
2000 2000
2000 2000
2000 2000
2000 2000
15 2000
2000 2000
输出
105 题意 : 给你一个字符串,每次只能在两端操作,增加一个字符或删掉一个字符,将其变成最长回文串
思路分析:一个马拉车可以预处理处理以每个位置为中心开始的最长回文子串,然后接下来的操作就是将一侧全部去掉,另一侧选择性的补齐一部分即可,每次补齐操作都是针对到两个边界的区间的,因此可以直接预处理处理
代码示例:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll maxn = 1e5+5; char s[maxn], now[maxn*2];
ll a[30], b[30];
ll len;
ll qa[maxn], qb[maxn], ha[maxn], hb[maxn];
ll qs[maxn], hs[maxn];
ll p[2*maxn]; void init() {
for(ll i = 1; i <= len; i++) qa[i] = qa[i-1]+a[s[i]-'a'];
for(ll i = 1; i <= len; i++) qb[i] = qb[i-1]+b[s[i]-'a']; for(ll i = len; i >= 1; i--) ha[i] = ha[i+1]+a[s[i]-'a'];
for(ll i = len; i >= 1; i--) hb[i] = hb[i+1]+b[s[i]-'a']; ll pos = 0; for(ll i = 1; i <= len; i++){
if (qa[i] < qa[pos]+qb[i]-qb[pos]){
pos = i;
qs[i] = qa[i];
}
else qs[i] = qa[pos]+qb[i]-qb[pos];
} pos = len+1;
for(ll i = len; i >= 1; i--){
if (ha[i] < ha[pos]+hb[i]-hb[pos]){
pos = i;
hs[i] = ha[i];
}
else hs[i] = ha[pos]+hb[i]-hb[pos];
}
} void Manacher()
{
for (ll i=1;i<=len;i++) now[2*i-1]='%',now[2*i]=s[i];
now[len=len*2+1]='%';
ll pos=0,R=0;
for (ll i=1;i<=len;i++)
{
if (i<R) p[i]=min(p[2*pos-i],R-i); else p[i]=1;
while (1<=i-p[i]&&i+p[i]<=len&&now[i-p[i]]==now[i+p[i]]) p[i]++;
if (i+p[i]>R) {pos=i;R=i+p[i];}
}
} int main () {
scanf("%s", s+1);
len = strlen(s+1); for(ll i = 0; i < 26; i++) scanf("%lld%lld", &a[i], &b[i]);
init();
Manacher(); ll ans = (1ll)<<60;
ll l, r;
for(ll i = 1; i <= len; i++){
p[i]--;
if (i%2){
ll ff = p[i]/2;
l = i/2-ff, r = i/2+ff+1;
}
else {
ll ff = p[i]/2;
l = i/2-ff-1, r = i/2+ff+1;
} ans = min(ans, qa[l]+hs[r]);
ans = min(ans, ha[r]+qs[l]);
//printf("%lld %lld %lld\n",l, r, ans);
}
printf("%lld\n", ans);
return 0;
}
递推预处理 + Manacher的更多相关文章
- Codeforces Round #271 (Div. 2) D. Flowers (递推 预处理)
We saw the little game Marmot made for Mole's lunch. Now it's Marmot's dinner time and, as we all kn ...
- HDU 4834 JZP Set(数论+递推)(2014年百度之星程序设计大赛 - 初赛(第二轮))
Problem Description 一个{1, ..., n}的子集S被称为JZP集,当且仅当对于任意S中的两个数x,y,若(x+y)/2为整数,那么(x+y)/2也属于S.例如,n=3,S={1 ...
- CodeForces 429 B Working out(递推dp)
题目连接:B. Working out 我想了很久都没有想到怎么递推,看了题解后试着自己写,结果第二组数据就 wa 了,后来才知道自己没有判选择的两条路径是否只是一个交点. 大概思路是:先预处理出每个 ...
- 【递推】【DFS】【枚举】Gym - 101246C - Explode 'Em All
网格里放了一些石块,一个炸弹能炸开其所在的行和列.问炸光石块至少要几个炸弹. 枚举不炸开的行数,则可以得出还要炸开几列. 为了不让复杂度爆炸,需要两个优化. 先是递推预处理出f(i)表示i的二进制位中 ...
- 利用Cayley-Hamilton theorem 优化矩阵线性递推
平时有关线性递推的题,很多都可以利用矩阵乘法来解决. 时间复杂度一般是O(K3logn)因此对矩阵的规模限制比较大. 下面介绍一种利用利用Cayley-Hamilton theorem加速矩阵乘法的方 ...
- 【66测试20161115】【树】【DP_LIS】【SPFA】【同余最短路】【递推】【矩阵快速幂】
还有3天,今天考试又崩了.状态还没有调整过来... 第一题:小L的二叉树 勤奋又善于思考的小L接触了信息学竞赛,开始的学习十分顺利.但是,小L对数据结构的掌握实在十分渣渣.所以,小L当时卡在了二叉树. ...
- HDU-4651 Partition 整数拆分,递推
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4651 题意:求n的整数拆为Σ i 的个数. 一般的递归做法,或者生成函数做法肯定会超时的... 然后要 ...
- 【BZOJ】1002: [FJOI2007]轮状病毒 递推+高精度
1002: [FJOI2007]轮状病毒 Description 给定n(N<=100),编程计算有多少个不同的n轮状病毒. Input 第一行有1个正整数n. Output 将编程计算出的不同 ...
- BZOJ4451 [Cerc2015]Frightful Formula 多项式 FFT 递推 组合数学
原文链接http://www.cnblogs.com/zhouzhendong/p/8820963.html 题目传送门 - BZOJ4451 题意 给你一个$n\times n$矩阵的第一行和第一列 ...
随机推荐
- P2P公司是如何进行风险管理的
关于P2P的风控很多人仍然是一知半解,甚至不少长期P2P圈内的资深玩家对此也是“既没吃过猪肉,也没见过猪跑”. 但是不可否认的是,作为一种跳过银行间接贷款融资模式的.一种在借款人和出借人之间直接发 ...
- UVA 437 "The Tower of Babylon" (DAG上的动态规划)
传送门 题意 有 n 种立方体,每种都有无穷多个. 要求选一些立方体摞成一根尽量高的柱子(在摞的时候可以自行选择哪一条边作为高): 立方体 a 可以放在立方体 b 上方的前提条件是立方体 a 的底面长 ...
- 安装 Sureface Hub 系统 Windows 10 team PPIPro 系统
本文告诉大家如何安装这个系统 本文的方法我自己没试过,如果失败了,不要打我 下载地址 中文版 https://pan.baidu.com/s/1gAJSSE6KB9JHXo4BT_VfmA 其他请看 ...
- the password has expired
Oracle提示错误消息ORA-28001: the password has expired,是由于Oracle11G的新特性所致, Oracle11G创建用户时缺省密码过期限制是180天(即6个月 ...
- Linux 内核释放函数和 kobject 类型
讨论中仍然缺失的一个重要事情是当一个 kobject 的引用计数到 0 时会发生什么. 创建 kobject 的代码通常不知道什么时候要发生这个情况; 如果它知道, 在第一位使用一个引 用计数就没有意 ...
- dotnet 控制台 Hangfire 后台定时任务
本文告诉大家如何在 dotnet core 的控制台通过 Hangfire 开启后台定时任务 首先需要安装 HangFire 这个 Nuget 库,通过这个库可以用来做定时任务,虽然很多时候都是在 A ...
- codeforces 572(Div2)A、B、C、D1、D2、E
Cdoeforces 572(Div2)A.B.C.D1.D2.E 传送门:https://codeforces.com/contest/1189 A.题意: 给你一串长为n的字符串,要求你将其切割为 ...
- AS优化
第一步:打开AS安装所在的位置,用记事本打开“红色框”选中的文件. 如图: 第二步:打开“studio64.exe.vmoptions”文件后修改里面的值,修改后如下: 1 2 3 4 5 6 7 8 ...
- springboot-集成WebSockets广播消息
一 WebScoketS 简介 RFC 6455 即 webSockets 协议提供了一种标准化的方式去建立全双工,双方面交流的通道在客户端和服务端甚至单一的TCP连接中进行通信: webSocket ...
- 分布式全局唯一ID生成策略
为什么分布式系统需要用到ID生成系统 在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识.如在美团点评的金融.支付.餐饮.酒店.猫眼电影等产品的系统中,数据日渐增长,对数据库的分库分表后需要有 ...