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 with b (Operation of the 1-st kind). The string is now bb.
  • Replace the 2-nd character b in bb with ca (Operation of the 2-nd kind). The string is now bca.
  • Replace the 1-st character b in bca with ca (Operation of the 2-nd kind). The string is now caca.
  • Replace the 2-nd character a in caca with b (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 operationsaaaaaaaaa 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的更多相关文章

  1. <JavaScript语言精粹>--<读书笔记三>之replace()与正则

    今天有人问我repalce(),他那个题目很有意思.我也不会做,于是我就去查,结果发现就是最基础的知识的延伸. 所以啊最基础的知识才是很重要的,千万不能忽略,抓起JS就写代码完全不知到所以然,只知道写 ...

  2. 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 ...

  3. js的replace函数入参为function时的疑问

    近期在写js导出excel文件时运用到replace方法,此处详细的记录下它各个参数所代表的的意义. 定义和用法 replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式 ...

  4. ORACLE 利用 REPLACE函数替换字段字符串

    REPLACE(string,s1,s2) string 希望被替换的字符或变量 s1 被替换的字符串 s2 要替换的字符串 SQL> select replace(he love you,he ...

  5. js 页面刷新location.reload和location.replace的区别小结

    reload 方法,该方法强迫浏览器刷新当前页面. 语法: location.reload([bForceGet]) 参数: bForceGet, 可选参数, 默认为 false,从客户端缓存里取当前 ...

  6. replace和translate的用法

    select replace ('111222333444','222','888') from dual;with tmp as(select 'aabb/123\:cde工人' s from du ...

  7. JavaScript replace() 方法

    参考:http://www.w3school.com.cn/jsref/jsref_replace.asp 需要有一点注意的是:可以是函数的形式做为返回值,如下: "test{0}" ...

  8. replace实现正则过滤替换非法字符

    html+js结构如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http: ...

  9. Replace 删除、替换函数精解示例

    '************************************************************************* '**模 块 名:Replace函数精解示例 '* ...

  10. angularjs 指令详解 - template, restrict, replace

    通过指令机制,angularjs 提供了一个强大的扩展系统,我们可以通过自定义指令来扩展自己的指令系统. 怎样定义自己的指令呢? 我们通过 Bootstrap UI来学习吧.这个项目使用 angula ...

随机推荐

  1. 谈一谈电商api的未来

    随着互联网的飞速发展,电商行业已经成为了现代消费的主流模式.在电商平台上,商品的交易.物流.支付等环节都需要使用API(Application Programming Interface)接口来实现信 ...

  2. 一篇关于获得拼多多商品详情 API的使用说明

    拼多多(Pinduoduo)是中国一家快速发展的电商平台,为了帮助开发者更好地接入拼多多,平台提供了丰富的 API 接口供开发者使用,其中包括获取拼多多商品详情的 API.接下来,我们将介绍如何使用拼 ...

  3. Go学习笔记1

    学习路线 2023-Go全链路工程师课纲 https://www.processon.com/view/link/63594cd97d9c0854f9ac855e 一.搭建环境 https://stu ...

  4. windows 网络模拟工具分享

    [下载地址] Releases · jagt/clumsy · GitHub [介绍] 无需安装 无需篡改和代理 系统级限制,不针对单个程序,但可以针对单个IP 离线也可以限制,随停随用 界面简单 [ ...

  5. 连接远程MySQL报错问题-Datagrip

    前言: 记录:DataGrip连接远程服务器MySQL数据库报错问题. 问题: 1.Communications link failure--会话连接失败 原因分析: 1.端口被防火墙了 2.MySQ ...

  6. 9. 用Rust手把手编写一个wmproxy(代理,内网穿透等), HTTP2改造篇之HPACK示例, 了解http2头信息如何处理

    9. 用Rust手把手编写一个wmproxy(代理,内网穿透等), HTTP2改造篇之HPACK示例, 了解http2头信息如何处理 项目 ++wmproxy++ gite: https://gite ...

  7. 算法学习笔记(3.1): ST算法

    ST表 在RMQ(区间最值)问题中,著名的ST算法就是倍增的产物.ST算法可以在 \(O(n \log n)\) 的时间复杂度能预处理后,以 \(O(1)\) 的复杂度在线回答区间 [l, r] 内的 ...

  8. CF431C

    题目简化和分析: k叉树,乍一看好像是树论,但我们通过分析条件,发现它每个阶段要做的事情一样,皆为:\(1\sim k\) 中选数字,这就很明显是DP. \(\mathit{f}_{i,0}\) 表示 ...

  9. Tinyalsa PCM API 实现深度剖析

    高级 Linux 音频架构 (ALSA) 用于为 Linux 操作系统提供音频和 MIDI 功能.它可以高效地支持所有类型的音频接口,从消费者声卡到专业的多通道音频接口.它支持全模块化的音频驱动.它是 ...

  10. Regions 题解

    Regions 这里提供一种时间复杂度不那么优秀但十分好写也好理解的做法. 题目大意 给定一颗 \(n\) 个节点的树,每个节点拥有一个颜色,进行若干次询问,每次询问给出两种颜色 \(A,B\),求所 ...