[ABC261G] Replace
Problem Statement
You are given two strings \(S\) and \(T\) consisting of lowercase English letters.
Takahashi starts with the string \(S\). He can perform K kinds of operations any number of times in any order.
The i-th operation is the following:
Pay a cost of \(1\). Then, if the current string contains the character \(C_i\), choose one of its occurrences and replace it with the string \(A_i\) . Otherwise, do nothing.
Find the minimum total cost needed to make the string equal \(T\). If it is impossible to do so, print −1.
Constraints
- \(1≤∣S∣≤∣T∣≤50\)
- \(1≤K≤50\)
- \(C\) is
a,b...z - \(1\le |A_i|\le 50\)
- \(S\), \(T\), and \(A_i\)are strings consisting of lowercase English letters.
- \(C_i\ne A_i\), regarding \(C_i\) as a string of length 1.
- All pairs \((C_i,A_i)\) are distinct.
Input
Input is given from Standard Input in the following format:
\(S\)
\(T\)
\(K\)
\(C_1\) \(A_1\)
\(C_2\) \(A_2\)
.
.
.
\(C_k\) \(A_k\)
Output
Print the minimum total cost needed to make the string equal \(T\). If it is impossible to do so, print −1.
Sample Input 1
ab
cbca
3
a b
b ca
a efg
Sample Output 1
4
Starting with S=ab, Takahashi can make T=cbca in four operations as follows:
- Replace the 1-st character
ain ab withb(Operation of the 1-st kind). The string is now bb. - Replace the 2-nd character
bin bb withca(Operation of the 2-nd kind). The string is now bca. - Replace the 1-st character
bin bca withca(Operation of the 2-nd kind). The string is now caca. - Replace the 2-nd character
ain caca withb(Operation of the 1-st kind). The string is now cbca.
Each operation incurs a cost of 1, for a total of 4, which is the minimum possible.
Sample Input 2
a
aaaaa
2
a aa
a aaa
Sample Output 2
2
Two operationsa → aaa → aaaaa incur a cost of 2, which is the minimum possible.
Sample Input 3
a
z
1
a abc
Sample Output 3
-1
No sequence of operations makes \(T\)=z from \(S\)=a.
妙到极致的区间 dp。
发现字符变为字符串不好做,所以我们反过来,字符串变为字符。同时发现变换方式有区间的痕迹,考虑区间 dp。
区间 dp 使用需要让区间变小。所以当 \(|A_i|=1\) 时,要特判。可以跑 Floyd。注意不要打错(打错 Floyd 调了好久
定义 \(dp_{l,r,c}\) 为 \(t[l,r]\) 变换成字符 \(c\) 的最小代价。这个区间 dp 难在转移。枚举使用哪一种变换方式。设使用第 \(i\) 种变换,那么 \(t[l,r]\) 变为 \(c_i\) 的代价为 \(t[l,r]\) 变为 \(A_i\) 的代价加 1。算完后我们把 Floyd 的结果跑一遍。算答案时我们也是计算 \(t[1,n]\) 变为 s 的代价。
所以我们唯一不会算的就是 \(t\) 的一个子串串变为另一个字符串的代价。设这个子串为 \(t[l,r]\),
考虑做另一个 dp 方程。设 \(g_{i,j}\) 为把 \(t_l\) 至 \(t_j\) 变为\(A_{i,1}\) 至 \(A_{i,k}\) 最小代价。转移时枚举最后一次变换的开头 \(k1\),那么\(g_{j,k}=\min \limits_{k1=l-1}^rg_{k1,k-1}+dp_{k1+1,j,A_{i,k}}\)
代码还挺绕的,建议写注释。同时要一步步理解。
#include<bits/stdc++.h>
using namespace std;
const int N=55;
char s[N],t[N],c[N],str[N][N];
int dis[27][27],dp[N][N][27],p,g[N][N],d[N],n,m,r;
int main()
{
memset(dis,0x3f,sizeof(dis));
memset(dp,0x3f,sizeof(dp));
scanf("%s%s%d",s+1,t+1,&p);
n=strlen(t+1),m=strlen(s+1);
for(int i=1;i<=p;i++)
{
scanf(" %c%s",&c[i],str[i]+1);
d[i]=strlen(str[i]+1);
if(d[i]==1)
dis[str[i][1]-'a'][c[i]-'a']=1;
// printf("%d\n",d[i]);
}
for(int i=1;i<=n;i++)
dp[i][i][t[i]-'a']=0;
for(int k=0;k<27;k++)
for(int i=0;i<27;i++)
for(int j=0;j<27;j++)
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
for(int len=1;len<=n;len++)
{
for(int l=1;l+len-1<=n;l++)//从t[l]至t[r]变到c的最小代价
{
r=l+len-1;
for(int i=1;i<=p;i++)//考虑第i次操作
{
if(d[i]>len)
continue;
memset(g,0x3f,sizeof(g));
g[l-1][0]=0;
for(int k=1;k<=d[i];k++)
{
for(int j=l-1;j<=r;j++)//把t[l]至t[j]变为str[i][1]至str[i][k]最小代价
{
for(int k1=l-1;k1<j;k1++)//已经把t[l]...t[k1]变成str[i][1]...str[i][k-1]
g[j][k]=min(g[j][k],g[k1][k-1]+dp[k1+1][j][str[i][k]-'a']);
}
}
// if(l==3&&r==4)
// printf("%d\n",g[3][1]);
dp[l][r][c[i]-'a']=min(dp[l][r][c[i]-'a'],g[r][d[i]]+1);
}
for(int i=0;i<27;i++)
for(int j=0;j<27;j++)
dp[l][r][i]=min(dp[l][r][i],dp[l][r][j]+dis[j][i]);
}
}
// printf("%d\n",dp[2][2][0]);
// printf("%d\n",dp[2][2][1]+dis[1][0]);
memset(g,0x3f,sizeof(g));
g[0][0]=0;
for(int k=1;k<=m;k++)
{
for(int j=0;j<=n;j++)//把t[l]至t[j]变为str[i][1]至str[i][k]最小代价
{
for(int k1=0;k1<j;k1++)//已经把t[l]...t[k1]变成str[i][1]...str[i][k-1]
g[j][k]=min(g[j][k],g[k1][k-1]+dp[k1+1][j][s[k]-'a']);
}
}
if(g[n][m]>1e9)
printf("-1\n");
else
printf("%d",g[n][m]);
return 0;
}
[ABC261G] Replace的更多相关文章
- <JavaScript语言精粹>--<读书笔记三>之replace()与正则
今天有人问我repalce(),他那个题目很有意思.我也不会做,于是我就去查,结果发现就是最基础的知识的延伸. 所以啊最基础的知识才是很重要的,千万不能忽略,抓起JS就写代码完全不知到所以然,只知道写 ...
- StackOverFlow排错翻译 - Python字符串替换: How do I replace everything between two strings without replacing the strings?
StackOverFlow排错翻译 - Python字符串替换: How do I replace everything between two strings without replacing t ...
- js的replace函数入参为function时的疑问
近期在写js导出excel文件时运用到replace方法,此处详细的记录下它各个参数所代表的的意义. 定义和用法 replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式 ...
- ORACLE 利用 REPLACE函数替换字段字符串
REPLACE(string,s1,s2) string 希望被替换的字符或变量 s1 被替换的字符串 s2 要替换的字符串 SQL> select replace(he love you,he ...
- js 页面刷新location.reload和location.replace的区别小结
reload 方法,该方法强迫浏览器刷新当前页面. 语法: location.reload([bForceGet]) 参数: bForceGet, 可选参数, 默认为 false,从客户端缓存里取当前 ...
- replace和translate的用法
select replace ('111222333444','222','888') from dual;with tmp as(select 'aabb/123\:cde工人' s from du ...
- JavaScript replace() 方法
参考:http://www.w3school.com.cn/jsref/jsref_replace.asp 需要有一点注意的是:可以是函数的形式做为返回值,如下: "test{0}" ...
- replace实现正则过滤替换非法字符
html+js结构如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http: ...
- Replace 删除、替换函数精解示例
'************************************************************************* '**模 块 名:Replace函数精解示例 '* ...
- angularjs 指令详解 - template, restrict, replace
通过指令机制,angularjs 提供了一个强大的扩展系统,我们可以通过自定义指令来扩展自己的指令系统. 怎样定义自己的指令呢? 我们通过 Bootstrap UI来学习吧.这个项目使用 angula ...
随机推荐
- 【pandas小技巧】--统计值作为新列
这次介绍的小技巧不是统计,而是把统计结果作为新列和原来的数据放在一起.pandas的各种统计功能之前已经介绍了不少,但是每次都是统计结果归统计结果,原始数据归原始数据,没有把它们合并在一个数据集中来观 ...
- python 自定义排序
需求:根据自定义的顺序就行排序 实现方法: res = [ {'name': 'RE', 'value': 2}, {'name': 'aa', 'value': 3}, {'name': 'RFM' ...
- 图解Spark Graphx基于connectedComponents函数实现连通图底层原理
原创/朱季谦 第一次写这么长的graphx源码解读,还是比较晦涩,有较多不足之处,争取改进. 一.连通图说明 连通图是指图中的任意两个顶点之间都存在路径相连而组成的一个子图. 用一个图来说明,例如,下 ...
- webgl 刷底色的基本步骤
1.在html中建立画布 <canvas id="canvas"><canvas> 2.在js中获取canvas画布 const canvas = docu ...
- C#开发的基础工具类集合 - 开源研究系列文章
今天发布一个基础工具类代码集合. 以前有发布过一个类似的类库(见博文: Magical平台类库代码分享 ),不过那个版本有点久了,也没有这次这个全面,这次发布的是一个很多地方用到的基础类库代码. 1. ...
- 2023-10-07:用go语言,给定n个二维坐标,表示在二维平面的n个点, 坐标为double类型,精度最多小数点后两位, 希望在二维平面上画一个圆,圈住其中的k个点,其他的n-k个点都要在圆外。
2023-10-07:用go语言,给定n个二维坐标,表示在二维平面的n个点, 坐标为double类型,精度最多小数点后两位, 希望在二维平面上画一个圆,圈住其中的k个点,其他的n-k个点都要在圆外. ...
- Python面向对象——封装
文章目录 内容回顾 封装 为何要隐藏? 作业 内容回顾 上节课复习: 1.编程范式/思想 面向过程 介绍: 核心是"过程"二字 过程就是"流水线" 过程终极奥义 ...
- https://www.oracle.com/au/cloud/free/
https://www.oracle.com/au/cloud/free/ "Oracle Cloud Free "免费云在线注册关于个人应用的用户在注册和试用的过程中遇到任何问题 ...
- PostgreSQL主备库搭建
pg主备库的搭建,首先需在2个节点安装pg软件,然后依次在2个节点配置主备. 本文采用os为CentOS7.6,pg版本使用14.2,以下为详细部署步骤. 本文两个节点的ip地址如下: [root@n ...
- React框架的基本运行原理与组件定义方式
React框架的基本运行原理 React的本质是内部维护了一套虚拟DOM树,这个虚拟DOM树就是一棵js对象树,它和真实DOM树是一致的,一一对应的. 当某一个组件的state发生修改时,就会生成一个 ...