[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
a
in ab withb
(Operation of the 1-st kind). The string is now bb. - Replace the 2-nd character
b
in bb withca
(Operation of the 2-nd kind). The string is now bca. - Replace the 1-st character
b
in bca withca
(Operation of the 2-nd kind). The string is now caca. - Replace the 2-nd character
a
in 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 ...
随机推荐
- 《SQL与数据库基础》08. 多表查询
目录 多表查询 多表关系 一对多 多对多 一对一 多表查询概述 分类 内连接 外连接 自连接 联合查询 子查询 分类 标量子查询 列子查询 行子查询 表子查询 案例 本文以 MySQL 为例 多表查询 ...
- 《SQL与数据库基础》05. SQL-DCL
目录 DCL 用户管理 权限控制 本文以 MySQL 为例 DCL 用户管理 查询有哪些用户: 1. USE mysql; SELECT * FROM user; 2. SELECT * FROM m ...
- msvc++中的预编译头文件pch.hpp和stdafx.h
预编译头文件 在 Visual Studio 中创建新项目时,会在项目中添加一个名为 pch.h 的"预编译标头文件". (在 Visual Studio 2017 及更高版本中, ...
- Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.so
在安装Docker以后,执行命令出现错误. Got permission denied while trying to connect to the Docker daemon socket at u ...
- Python从0到1丨详解图像锐化的Sobel、Laplacian算子
本文分享自华为云社区<[Python从零到壹] 五十八.图像增强及运算篇之图像锐化Sobel.Laplacian算子实现边缘检测>,作者: eastmount . 一.Sobel算子 So ...
- 堆的原理以及实现O(lgn)
大家好,我是蓝胖子,我一直相信编程是一门实践性的技术,其中算法也不例外,初学者可能往往对它可望而不可及,觉得很难,学了又忘,忘其实是由于没有真正搞懂算法的应用场景,所以我准备出一个系列,囊括我们在日常 ...
- Go 语言开发环境搭建
Go 语言开发环境搭建 目录 Go 语言开发环境搭建 一. GO 环境安装 1.1 下载 1.2 Go 版本的选择 1.3 安装 1.3.1 Windows安装 1.3.2 Linux下安装 1.3. ...
- xgo多线程
import threading import time #导入xgoedu from xgoedu import XGOEDU from xgolib import XGO #导入xgolib # ...
- maven error
1 [INFO] Assembling webapp [crm9] in [/home/wukongcrm/72crm-java/target/ROOT] 2 [INFO] Processing wa ...
- K8S太庞大,这款PasteSpider绝对适合你!一款轻量级容器部署管理工具
PasteSpider采用.netcore编写,运行于linux服务器的docker/podman里面,涉及的技术或者工具有podman/docker,registry,nginx,top,ssh,g ...