[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 ...
随机推荐
- grinder使用入门
安装配置 自动安装脚本编写 移步我的github下载脚本,只要修改下配置信息,即可完成安装 环境变量设置:
- assembleDebug太慢的问题调查以及其他
Preface 最近在做flutter上的音频和视频方面的探索. 需要用到一些视屏区域截取,视屏导出成序列图等等. 这是昨天晚上到今天早上解决的一些问题的汇总,可能先后顺序之类的会记错: 此文目的用于 ...
- Solution -「GXOI / GZOI 2019」宝牌一大堆
Description Link. Summarizing the fucking statement is the last thing in the world I ever want to do ...
- Teamcener AWC Solr链接被拒
1.检查安装Solr安装情况 2.在tem上勾选添加 安装完成后,总共有2个文件夹需要注意,一个 solr-版本 的文件夹,一个 TcFTSindexer 的文件夹 如果是solr安装的是服务,则不需 ...
- HarmonyOS 4.0 实况窗上线!支付宝实现医疗场景智能提醒
本文转载自支付宝体验科技,作者是蚂蚁集团客户端工程师博欢,介绍了支付宝如何基于 HarmonyOS 4.0 实况窗实现医疗场景履约智能提醒. 1.话题背景 8 月 4 日,华为在 HDC(华为 202 ...
- oracle监听配置与防火墙问题
在建好pdb容器后,需配置网络,才能从客户端连接服务器端 1.首先查看pdb容器的服务名 lsnrctl status ... Service "19cdb" has 1 inst ...
- Go语言常用标准库——context
文章目录 为什么需要Context 基本示例 全局变量方式 通道方式 官方版的方案 Context初识 Context接口 Background()和TODO() With系列函数 WithCance ...
- Android项目Library导入的问题整理
Android项目Library导入的问题整理 本来帮助朋友找寻一下android的一些特效的demo,结果找到了一个,朋友试验可以,自己却是在导入项目需要的library的时候总是出问题,真的很是丢 ...
- Oracle的差异增量备份和累积增量备份
在rman增量备份中,有差异增量和累积增量的概念. 差异增量:是备份上级及同级备份以来所有变化的数据块,差异增量是默认增量备份方式累积增量:是备份上级备份以来所有变化的块 累积增量是备份上级备份以来所 ...
- [SUCTF 2019]CheckIn 1
看到字符upload 就想到了文件上传漏洞 就先上传一个一句话木马试试 似乎直接上传不成功,可能是有什么过滤 再上传一个包含一句话木马的图片试试 发现提示不能是图片,这时候就不会了,在网上找了一下wp ...