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题目

posted @ 2018-08-17 21:48  lqxssf  阅读(192)  评论(0编辑  收藏  举报