题意:给出两个字符串A与B,然后有3种操作,分别是添加一个字符,删除一个字符和修改一个字符,求最少操作多少次可能让A转化为B。
这个题其实不难,考虑
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]为A串的前
i
i
i位转化为B串的前
j
j
j位的最小代价,那么对于当前的决策点
(
i
,
j
)
(i,j)
(i,j)的转移只有一下的一些情况。
d
p
[
i
]
[
j
]
=
{
d
p
[
i
−
1
]
[
j
−
1
]
A
[
i
]
=
B
[
j
]
m
i
n
(
d
p
[
i
]
[
j
−
1
]
,
d
p
[
i
−
1
]
[
j
]
,
d
p
[
i
−
1
]
[
j
−
1
]
)
+
1
A
[
i
]
≠
B
[
j
]
dp[i][j]= \left\{ \begin{aligned} &dp[i-1][j-1] \ A[i]=B[j] \\ &min(dp[i][j-1],dp[i-1][j],dp[i-1][j-1])+1 \ A[i] \ne B[j]\\ \end{aligned} \right.
dp[i][j]={dp[i−1][j−1] A[i]=B[j]min(dp[i][j−1],dp[i−1][j],dp[i−1][j−1])+1 A[i]̸=B[j]
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const ll INF=LONG_LONG_MAX;
const int N=4e3+7;
int dp[N][N];
char s1[N],s2[N];
int main() {
scanf("%s%s",s1+1,s2+1);
int len1=strlen(s1+1);
int len2=strlen(s2+1);
for(int j=1;j<=len2;j++)
dp[0][j]=j;
for(int i=1;i<=len1;i++)
dp[i][0]=i;
dp[0][0]=0;
for(int i=1;i<=len1;i++)
for(int j=1;j<=len2;j++) {
if(s1[i]==s2[j]) dp[i][j]=dp[i-1][j-1];
else dp[i][j]=min(dp[i-1][j-1],min(dp[i-1][j],dp[i][j-1]))+1;
}
printf("%d\n",dp[len1][len2]);
return 0;
}