2018.8.17 题解 2018暑假集训之编辑距离
应该是一个很经典的题目了吧
上题面描述
概念
字符串的编辑距离,又称为Levenshtein距离,由俄罗斯的数学家Vladimir Levenshtein在1965年提出。是指利用字符操作,把字符串A转换成字符串B所需要的最少操作数。其中,字符操作包括:
- 删除一个字符 a) Insert a character
- 插入一个字符 b) Delete a character
- 修改一个字符 c) Replace a character
例如对于字符串"if"和"iff",可以通过插入一个'f'或者删除一个'f'来达到目的。
一般来说,两个字符串的编辑距离越小,则它们越相似。如果两个字符串相等,则它们的编辑距离(为了方便,本文后续出现的“距离”,如果没有特别说明,则默认为“编辑距离”)为0(不需要任何操作)。不难分析出,两个字符串的编辑距离肯定不超过它们的最大长度(可以通过先把短串的每一位都修改成长串对应位置的字符,然后插入长串中的剩下字符)。
问题描述
给定两个字符串A和B,求字符串A至少经过多少步字符操作变成字符串B。
对于这个问题来讲我们首先想到的是用bfs解决
然而发现会TLE Q_Q
对于求最值的问题,我们考虑搜索、dp、贪心
已经排除搜索(同样易证得贪心不可行)于是考虑用dp解决
本题有一个很类似的问题 题目传送门 同样是对两个字符串上的dp
同样的在前面我们讲过一个纸牌问题解决如何“两个同时取”
而这个题只有两个变量 就是两个串取到了第几个位置
综上所述
我们分两种情况考虑
(1)a[i]==b[j] dp[i][j]=dp[i-1][j-1](该字符不变)
(2)a[i]!=b[j] dp[i][j]=min(dp[i-1][j-1],min(dp[i-1][j],dp[i][j-1]))+1(更改、插入、删除)
上代码吧
#include<iostream>
#include<cstring>
using namespace std;
int dp[3050][3050],lena,lenb;
char a[3050],b[3050];
int main()
{
gets(a+1),gets(b+1);
lena=strlen(a+1),lenb=strlen(b+1);
for(int i=1;i<=lena;i++)dp[i][0]=i;
for(int j=1;j<=lenb;j++)dp[0][j]=j;
for(int i=1;i<=lena;i++)
{
for(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-1],min(dp[i-1][j],dp[i][j-1]))+1;
}
}
printf("%d",dp[lena][lenb]);
return 0;
}
也是一个经典的字符串dp题目
/*====年轻人,瞎搞是出不了省一的,这就是现实====*/