P2758 编辑距离
Solution
经典dp问题,设dp[i][j]为处理完A字符串的前i个字符(包括第i个)和处理完B字符串前j个字符(包括第j个)时最小的编辑距离,n为A的长度,m为B的长度,那么总共对应着四种情况:
- 如果A[i] == B[j],不做任何操作,dp[i][j] = dp[i - 1][j - 1]
- 删除A的一个字符,dp[i][j] = dp[i - 1][j] + 1
- 往A中添加一个字符,dp[i][j] = dp[i][j - 1] + 1
- 直接替换字符,dp[i][j] = dp[i - 1][j - 1] + 1
将以上四种情况(其实是三种,因为如果不做任何操作次数一定是最少的)求最小值后dp[n][m]即是答案
关于初始化:
- dp[i][0]即当B为空时,一直删除A中字符即可,所以dp[i][0] = i( i从1到n )
- dp[0][i]即当A为空时,一直往A中增添字符即可,所以dp[0][i] = i( i从1到n )
注意字符串从0开始,dp数组从1开始
Code
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
int dp[2010][2010];
int main() {
string s1, s2;
cin >> s1 >> s2;
int n = s1.size(), m = s2.size();
for (int i = 1; i <= n; i++) dp[i][0] = i;
for (int i = 1; i <= m; i++) dp[0][i] = i;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
if (s1[i - 1] != s2[j - 1])
dp[i][j] = min(min(dp[i - 1][j] + 1, dp[i][j - 1] + 1), dp[i - 1][j - 1] + 1);
else dp[i][j] = dp[i - 1][j - 1];
cout << dp[n][m] << endl;
return 0;
}