題面
題目描述
設A和B是兩個字元串。我們要用最少的字元操作次數,将字元串A轉換為字元串B。這裡所說的字元操作共有三種:
1、删除一個字元;
2、插入一個字元;
3、将一個字元改為另一個字元;
皆為小寫字母
輸入格式:
第一行為字元串A;第二行為字元串B;字元串A和B的長度均小于2000。
輸出格式:
隻有一個正整數,為最少字元操作次數。
Input
sfdqxbw
gfdgw
Output
4
題解
一道DP裸體
先設一下狀态
設f[i][j]表示串S1前i個字元到串S2前j個字元的編輯距離
看一看每一個f[i][j]可以怎麼得到:
如果目前有S1[i]=S2[j]那麼f[i][j]=f[i-1][j-1],直接由前面的狀态就可以得到
否則:
1. 可以由i-1和j-1的比對情況加上一次修改操作
2. 可以由i-1和j 的比對情況加上一次删除操作
3. 可以由i 和j-1的比對情況加上一次添加操作
是以狀态轉移方程就可以得出來了
後面就不用寫了,直接看代碼吧
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
string s1,s2;//初始字元串
int l1,l2;
int f[][];
int main()
{
cin>>s1>>s2;
l1=s1.length();
l2=s2.length();
memset(f,,sizeof(f));
//f[i][j]表示把 s1前i位變為 s2的前j位的 最短編輯距離
for(int i=;i<=l2;++i)
f[][i]=i;
for(int i=;i<=l1;++i)
f[i][]=i;
for(int i=;i<=l1;++i)
{
for(int j=;j<=l2;++j)
{
if(s1[i-]==s2[j-])
f[i][j]=min(f[i][j],f[i-][j-]);//如果兩位相同
else
f[i][j]=min(f[i][j],f[i-][j-]+);//上一位的基礎上加"替換"
f[i][j]=min(f[i][j],f[i][j-]+);//上一個的基礎上加"添加"
f[i][j]=min(f[i][j],f[i-][j]+);//上一位的基礎上加"删除"
}
}
cout<<f[l1][l2]<<endl;
return ;
}