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. 【LaTeX】制作 PPT(更新中)

    目录 Beamer 模板 特性 frame 与 slide \pause itemize 中的尖括号 <strat-end> 参考资料 Beamer 模板 PPT 推荐用 Beamer 模 ...

  2. 《SQL与数据库基础》21. 分库分表(一)

    目录 分库分表(一) 拆分策略 垂直拆分 垂直分库 垂直分表 水平拆分 水平分库 水平分表 技术实现 MyCat概述 概念介绍 环境准备 目录介绍 MyCat入门 配置 分片配置(schema.xml ...

  3. 使用pycharm脚本发送钉钉群通知

    使用Pychon脚本发送钉钉群通知 我们可以使用钉钉的机器人助手发送群通知,只需要非常简单的配置就可以实现,而没有任何的成本. 1) 首先我们要在钉钉群里添加一个机器人助手 选择智能群助手,然后选择添 ...

  4. Codeforces 1463D Pairs

    题意 对于数字\(1\)~\(2n\),可以构造出\(n\)个二元组,对于\(n\)个二元组,选择一个数组\(x\),留下\(x\)个二元组的最小值,留下\(n-x\)个二元组的最大值,其构成了一个集 ...

  5. 2023羊城杯RE部分

    vm_wo 代码copy下来调了一下 vm_body[0]=input[i] vm_body[1]=vm_body[0]>>1 v12=vm_body[0] vm_body[2]=v12& ...

  6. Docker常见使用

    DockerFile: FROM openjdk:8 MAINTAINER guotong ADD lpl-1.0-SNAPSHOT.jar lpl-1.0-SNAPSHOT.jar EXPOSE 8 ...

  7. Python基础——变量、常量、数字类型、四 列表list、五 字典dict、六 布尔bool、垃圾回收机制、用户交互、运算符、流程控制

    文章目录 变量 一 引入 一.什么是变量? 二.为什么要有变量? 三.怎么使用变量(先定义.后使用) 3.1.变量的定义与使用 3.2.变量名的命名规范 3.3.变量名的命名风格 3.4.变量值的三大 ...

  8. 循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(9) -- 实现系统动态菜单的配置和权限分配

    在WPF应用端开发,它的界面类似于Winform端,因此我们也需要对系统的菜单进行动态配置,这样才能把系统的功能弹性发挥到极致,通过动态菜单的配置方式,我们可以很容易的为系统新增所需的功能,通过权限分 ...

  9. 网络层IP数据包

    网络层 功能 选择数据通过网络(IP地址)的最佳路径 协议字段 版本号(4bit):指IP协议版本.并且通信双方使用的版本必须一致,目前我们使用的是IPv4,表示为0100 十进制 是4 首部长度(4 ...

  10. 前端JavaScript编码规范 和react编码规范

    JavaScript编码规范 点击链接查看:https://github.com/ecomfe/spec/blob/master/javascript-style-guide.md 前端React编码 ...