1. 程式人生 > >【DP】編輯距離

【DP】編輯距離

turn 問題 行為 n-1 bit min sizeof pre 一個

傳送門:一本通評測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 }

 

【DP】編輯距離