https://www.luogu.com.cn/problem/P2758
思路:
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]表示把字符串
a
a
a的
[
1
…
i
]
[1…i]
[1…i]部分转换成字符串
b
b
b的
[
1
…
j
]
[1…j]
[1…j]部分所需要的最少操作次数。如果
a
[
i
]
=
b
[
j
]
a[i]=b[j]
a[i]=b[j],可得
d
p
[
i
]
[
j
]
=
d
p
[
i
−
1
]
[
j
−
1
]
+
1
dp[i][j]=dp[i-1][j-1]+1
dp[i][j]=dp[i−1][j−1]+1;否则考虑三种不同的操作:
(
1
)
(1)
(1)删除,对应的情况为
d
p
[
i
−
1
]
[
j
]
+
1
dp[i-1][j]+1
dp[i−1][j]+1;
(
2
)
(2)
(2)插入,对应的情况为
d
p
[
i
]
[
j
−
1
]
+
1
dp[i][j-1]+1
dp[i][j−1]+1;
(
3
)
(3)
(3)替换,对应的情况为
d
p
[
i
−
1
]
[
j
−
1
]
+
1
dp[i-1][j-1]+1
dp[i−1][j−1]+1;取最小的即可。注意当
i
、
j
=
0
i、j=0
i、j=0时的初始化。
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define eps 1e-10
#define pr pair<int,int>
using namespace std;
typedef long long ll;
const int maxn=2005;
char a[maxn],b[maxn];
int dp[maxn][maxn];
int main()
{
scanf("%s%s",a+1,b+1);
int n=strlen(a+1),m=strlen(b+1);
for(int i=1;i<=m;i++)
dp[0][i]=i;
for(int i=1;i<=n;i++)
dp[i][0]=i;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i]==b[j])
dp[i][j]=dp[i-1][j-1];
else
{
dp[i][j]=min(dp[i-1][j],dp[i][j-1])+1;
dp[i][j]=min(dp[i][j],dp[i-1][j-1]+1);
}
}
}
printf("%d\n",dp[n][m]);
return 0;
}