1. 程式人生 > >51nod 1183 編輯距離【線性dp+類似最長公共子序列】

51nod 1183 編輯距離【線性dp+類似最長公共子序列】

ima else ems 俄羅斯 hid ace mem std 類型

1183 編輯距離 基準時間限制:1 秒 空間限制:131072 KB 分值: 0 難度:基礎題 技術分享 收藏 技術分享 關註 編輯距離,又稱Levenshtein距離(也叫做Edit Distance),是指兩個字串之間,由一個轉成另一個所需的最少編輯操作次數。許可的編輯操作包括將一個字符替換成另一個字符,插入一個字符,刪除一個字符。 例如將kitten一字轉成sitting: sitten (k->s) sittin (e->i) sitting (->g) 所以kitten和sitting的編輯距離是3。俄羅斯科學家Vladimir Levenshtein在1965年提出這個概念。
給出兩個字符串a,b,求a和b的編輯距離。 Input
第1行:字符串a(a的長度 <= 1000)。
第2行:字符串b(b的長度 <= 1000)。
Output
輸出a和b的編輯距離
Input示例
kitten
sitting
Output示例
3

【分析】:
設dp[i][j]代表a字符串前i個變形 b字符串前j個最小操作步數;
此題類型和求兩字符串最長公共子序列有相同部分,但最長公共序列對相同字符位置沒有要求,但在此題中則是解題關鍵,
若兩位置相同,則不需任何操作,但若兩相同部分之間相錯n位,則需增加n次操作,同時還要考慮最優解;
同時dp[i][0]=dp[0][i]=i;

(1) 必須 S[i] == T[j], 這時前i – 1和j – 1位都已經對齊了,這部分肯定要最少扣分。這種情況下最少的扣分是dp(i-1,j-1)
(2) 和(1)類似,S[i]≠T[j],這種情況下最少的扣分是dp(i - 1, j – 1) + 1
(3) S的前i位和T的前(j – 1)位已經對齊了,這部分扣分也要最少。這種情況下最少的扣分是dp(i, j - 1) + 1
(4) S的前(i - 1)位已經和T的前j位對齊了,這部分扣分要最少。這種情況下最少的扣分是dp(i - 1, j) + 1

這樣就能得到狀態轉移方程:

dp(i,j) = min(dp(i – 1, j – 1) + ( S[i] == T[j] ? 0:1 ), dp(i – 1,j ) + 1, dp(i, j – 1) + 1)

【代碼】:

技術分享
#include <bits/stdc++.h>  
using namespace std;  
const int AX = 1e3+66;  
  
int dp[AX][AX];  
char a[AX];  
char b[AX];  
  
int main(){   
    while(~scanf("%s%s",a,b)){  
        memset(dp,0,sizeof(dp));  
        int n = strlen(a);  
        int m = strlen(b);  
        for( int i = 1 ; i <= n ; i++ ){  
            dp[i][0] = i;  
        }  
        for( int j = 1 ; j <= m ; j++ ){  
            dp[0][j] = j;  
        }  
        for( int i = 1 ; i <= n ; i++ ){  
            for( int j = 1 ; j <= m ;j++ ){  
                if( a[i-1] != b[j-1] )  
                    dp[i][j] = min(dp[i-1][j-1],min(dp[i-1][j],dp[i][j-1])) + 1;  
                else dp[i][j] = dp[i-1][j-1];  
            }  
        }  
        printf("%d\n",dp[n][m]);  
    }  
    return 0;  
}  
View Code

51nod 1183 編輯距離【線性dp+類似最長公共子序列】