[LuoGu] P2758 编辑距离

\(\color{red}{\mathcal{Description}}\)

\(A\)\(B\) 是两个字符串。我们要用最少的字符操作次数,将字符串 \(A\) 转换为字符串 \(B\) 。这里所说的字符操作共有三种:

1、删除一个字符;

2、插入一个字符;

3、将一个字符改为另一个字符;

皆为小写字母

\(\color{red}{\mathcal{Input\ Format}}\)

第一行为字符串 \(A\) ;第二行为字符串 \(B\)

\(\color{red}{\mathcal{Output\ Format}}\)

只有一个正整数,为最少字符操作次数。

\(\color{red}{\mathcal{DataSize\ Agreement}}\)

字符串 \(A\)\(B\) 的长度均小于\(2000\)

\(\color{red}{\mathcal{Solution}}\)

考虑用dp

\(dp[i][j]\) 表示字符串 \(A\) 的前 \(i\) 位转换为字符串 \(B\) 的前 \(j\) 位需要最小的操作次数

再考虑状态的转移.这里有个小弯,其实操作一与操作二可以归为一个状态,因为仔细想想就知道没有区别.

所以得出状态转移方程

\[dp[i][j]=\begin{cases}dp[i-1][j-1]&(A[i]=B[j])\\max(dp[i-1][j],dp[i][j-1],dp[i-1][j-1])+1&(A[i]\neq B[j])\end{cases}\ \ \ \ (1 \leq i \leq lengthA, 1 \leq j \leq lengthB)\]
初始化 \(dp[i][0]=i\),\(dp[0][j]=j\) \((1 \leq i \leq lengthA, 1 \leq j \leq lengthB)\)

\(\color{red}{\mathcal{Code}}\)

#include <bits/stdc++.h>
#define LL long long
#define reg register

using namespace std;

const int kLen = 2e3 + 10;

int dp[kLen][kLen];
char A[kLen], B[kLen];

int main() {
  scanf("%s%s", A + 1, B + 1);
  int lena = strlen(A + 1), lenb = strlen(B + 1);
  for (reg int i = 1; i <= lena; ++i)
    dp[i][0] = i;
  for (reg int i = 1; i <= lenb; ++i)
    dp[0][i] = i;
  for (reg int i = 1; i <= lena; ++i)
    for (reg int j = 1; j <= lenb; ++j) {
      if (A[i] == B[j]) {
        dp[i][j] = dp[i - 1][j - 1];
      } else {
        dp[i][j] = min(dp[i - 1][j], min(dp[i][j - 1], dp[i - 1][j - 1])) + 1;
      }
    }
  printf("%d\n", dp[lena][lenb]);
  return 0;
}

转载于:https://www.cnblogs.com/1miharu/p/11328951.html

请使用c++14 ## 题目描述 一个有 $n$ 个顶点的环 $C$ 是一个图,其中第 $i$ 个顶点和第 $i+1$ 个顶点(对于 $i=1,2,\dots,n-1$)通过一条边相连,并且第 $n$ 个顶点和第 $1$ 个顶点也通过一条边相连,其中 $C$ 的顶点编号为 $1$ 到 $n$。 有 $n$ 个硬币,每个硬币编号为 $1$ 到 $n$ 中的一个数,且不同硬币的编号可以相同。最初,$C$ 的每个顶点上都放有一个硬币。然后,任意两个顶点可以互相交换各自的硬币。对于环 $C$ 上的一条路径 $w=(v_1, v_2, \dots, v_k)$,可以依次按 $i=1,2,\dots,k-1$ 的顺序,将 $v_i$ 和 $v_{i+1}$ 上的硬币交换,称为一次路径交换。这里,路径 $w$ 是由 $k$($k \geq 1$)个顶点依次组成的序列,相邻两个顶点不同且在 $C$ 中相邻,可以理解为遍历 $C$ 时依次经过的顶点。$k$ 称为路径 $w$ 的长度。对于长度 $k \geq 2$ 的路径,路径交换过程中会发生 $k-1$ 次硬币交换;对于长度为 1 的路径,则没有交换。如图所示,是在一个有 4 个顶点的环上按照路径 $(2, 1, 4, 1)$ 进行路径交换的过程: ![](https://cdn.luogu.com.cn/upload/image_hosting/aae2egnc.png) 现在给定 $C$ 的初始硬币分布以及目标硬币分布,你需要通过若干次路径交换,使得初始分布变为目标分布,并且使交换的总次数最小。 例如,在上图中,路径交换 $(2, 1, 4, 1)$ 共交换了 3 次,但通过路径 $(1, 2)$ 一次交换也可以得到相同的目标配置。 给定环 $C$ 的顶点数量、初始硬币分布和目标硬币分布,编写程序输出将初始配置变为目标配置所需路径交换中最少的硬币交换次数。 如果不存在任何一种路径交换能够得到目标配置,输出 -1。 ## 输入格式 输入从标准输入读入。 第一行包含一个整数 $n$,表示环 $C$ 的顶点数,$1 \leq n \leq 3000$。 第二行包含 $n$ 个整数,第 $i$ 个整数表示初始时第 $i$ 个顶点上的硬币编号(可能有重复),所有值均为 $1$ 到 $n$ 之间的整数。 第三行包含 $n$ 个整数,第 $i$ 个整数表示目标状态下第 $i$ 个顶点上的硬币编号(可能有重复),所有值均为 $1$ 到 $n$ 之间的整数。 ## 输出格式 输出一个整数,表示通过路径交换变换为目标配置时,最少硬币交换次数。如果无法达到目标配置,输出 -1。 ## 输入输出样例 #1 ### 输入 #1 ``` 4 4 3 2 1 3 4 2 1 ``` ### 输出 #1 ``` 1 ``` ## 输入输出样例 #2 ### 输入 #2 ``` 6 2 1 1 2 2 1 1 2 2 2 1 1 ``` ### 输出 #2 ``` 7 ``` ## 输入输出样例 #3 ### 输入 #3 ``` 6 4 1 3 6 2 5 6 2 1 3 4 5 ``` ### 输出 #3 ``` -1 ```
最新发布
11-13
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值