[LGP2758]编辑距离

题目

题目描述

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

1、删除一个字符;

2、插入一个字符;

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

!皆为小写字母!

输入格式

第一行为字符串A;第二行为字符串B;字符串A和B的长度均小于2000。

输出格式

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

输入输出样例

输入 #1

sfdqxbw
gfdgw

输出 #1

4

题目分析

当前的状态会影响到后续的状态。

我们可以考虑DP

dpi,j表示把a1i 转换为b1j需要的最少步数

那么dpi,j应该就由四种状态转移过来:立改废存

  1. 什么都不变

这样需要ai=bj,然后直接dpi,j=dpi1,j1,也就是直接接下来就可以了

  1. 插入操作之后得到

那么就应该是让a1i操作得到b1j1,那么只需要在ai后面插入bj,就可以把ai转换成bj1之后再加一步,即dpi,j=dpi,j1+1就可以得到bj

  1. 删除操作之后得到

就应该让a1i1操作之后得到b1j,然后再把ai删掉,就能通过ai得到bj,即dpi,j=dpi1,j+1

  1. 替换操作之后得到

那么就是ai1操作之后得到bj1,然后把ai改成bj,前提是aibj,即dpi,j=dpi1,j1+1

如果ai=bj,那么就直接接下来,否则就剩下三种情况的最小值。

状态转移方程

dpi,j={dpi1,j1ai=bjmin(dpi1,j,dpi,j1,dpi1,j1)+1aibj

初始状态

可以知道初始状态应该是dpi,0dp0,j

也很容易得到把a1i 变成0(没有串)需要删除i

同样dp0,j=j

结束状态

dplena,lenb

Code

#include <cstdio>
#include <cstring>
#include <iostream>

int lena,lenb;
char a[2001],b[2001];
int dp[2001][2001];

int main()
{
	scanf("%s%s",a+1,b+1);
	lena=strlen(a+1); lenb=strlen(b+1);
	for(register int i=1;i<=lena;++i)
	{
		dp[i][0]=i;
		for(register int j=1;j<=lenb;++j)
		{
			dp[0][j]=j;
			if(a[i]==b[j]) dp[i][j]=dp[i-1][j-1]; else
			{
				dp[i][j]=std::min(std::min(dp[i][j-1],dp[i-1][j]),dp[i-1][j-1])+1;
			}
		}
	}
	printf("%d\n",dp[lena][lenb]);
	return 0;
}
posted @   IdanSuce  阅读(33)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示