【DP】编辑距离

传送门:一本通评测1276

【题目描述】

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

1、删除一个字符;

2、插入一个字符;

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

对任意的两个字符串A和B,计算出将字符串A变换为字符串B所用的最少字符操作次数。

【输入】

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

【输出】

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

【输入样例】

sfdqxbw
gfdgw

【输出样例】

    4

【思路】

动态规划思想,题目问的是字符串a到字符串b的编辑距离。动态规划有最优子问题结构,子问题的形式和原问题结构相似,且规模减小。那么在考虑问题的时候,往前想一步:

·如果字符串a前alen-1个字符已经和b相同,那么当前a到b的编辑距离就是1(删除最后一个)

·如果字符串a和b的前blen-1个字符相同,那么当前a到b的距离也是1(添加一个)
·如果a的前alen-1个字符和b的blen-1个字符已经相同,如果a的最后一个字符和b的最后一个字符相同,那么a到b的编辑距离为0,否则为1(改变一次)
设状态为dp[i][j],表示字符串a的前i个字符到字符串b的前j个字符的编辑距离,由以上分析,可以写出该dp的状态转移方程:

dp[i][j]=min(dp[i-1][j]+1,dp[i][j-1]+1,dp[i-1][j-1])(a的第i个字符和b的第j个字符相同)
dp[i][j]=min(dp[i-1][j]+1,dp[i][j-1]+1,dp[i-1][j-1]+1)(a的第i个字符和b的第j个字符不同)

详细代码如下:
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define maxn 2000+5
 4 int d[maxn][maxn];
 5 int min(int a,int b,int c)
 6 {
 7     if(a>b) swap(a,b);
 8     if(a>c) swap(a,c);
 9     return a; 
10  } 
11 int main()
12 {
13     char a[maxn],b[maxn];
14     cin>>a;
15     cin>>b;
16     memset(d,0,sizeof(d));
17     int len1=strlen(a);
18     for(int i=1;i<=len1;i++)
19     {    
20         d[i][0]=i;
21     }
22     int len2=strlen(b);
23     for(int i=1;i<=len2;i++)
24     {
25         d[0][i]=i;
26     } 
27     for(int i=1;i<=len1;i++)
28     {
29         for(int j=1;j<=len2;j++)
30         {
31             d[i][j]=min(d[i-1][j]+1,d[i][j-1]+1,d[i-1][j-1]+(a[i-1]==b[j-1]?0:1));
32         }
33     }
34     cout<<d[len1][len2]<<endl;
35     return 0;
36 }

 

 
posted @ 2018-10-12 21:33  aq_seabiscuit  阅读(503)  评论(0编辑  收藏  举报