题目描述
小蓝拥有两个字符串 S,TS,T。他希望通过如下操作使得字符 SS 转换为字符串 TT。
操作有一下三种:
- 删除一个字符。
- 插入一个字符。
- 将一个字符改为另一个字符。
问最少需要操作多少次才可以使得字符串 SS 转换为字符串 TT。
输入描述
输入第一行包含一个字符串 SS。
输入第二行包含一个字符串 TT。
1 \leq |S|,|T| \leq 2\times 10^31≤∣S∣,∣T∣≤2×103,保证 SS、TT 只包含小写字母。
输出描述
输出一个整数表示答案。
输入输出样例
示例 1
输入
abc
aa
输出
2
运行限制
- 最大运行时间:3s
- 最大运行内存: 128M
思路:其实看破这个题,状态转移方程有点像最长上升子序列
有四种操作,分别为:
1.删除:dp(i-1,j)+1
把字符串A的第i个字符删除,操作次数加一
2.添加:dp(i,j-1)+1
在字符串A末添加字符串B的第j个字符,操作次数加一
3.替换:dp(i-1,j-1)+1
将字符串A的第i个字符替换成字符串B的第j个字符,操作次数加一
4.不变:dp(i-1,j-1)
如果字符串A的第i个字符等于字符串B的第j个字符,什么都不做
第三步处理边界情况
就把dp[i][0]
和dp[0][i]
赋值为i
就可以了
因为空字符串变成i
个字符的话,i
次操作便可以了
AC代码
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<set>
#include<cmath>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<algorithm>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define PII pair<int,int>
#define inf 0x3f3f3f3f
#define endl "\n"
typedef long long ll;
using namespace std;
int t,n,m,k;
string s;
const int maxn = 2e3+5;
string a,b;
int dp[maxn][maxn];
int ans;
void solve()
{
cin >> a >> b;
int len_a = a.size();
int len_b = b.size();
for(int i = 1 ; i <= len_a ; i++) dp[i][0] = i;
for(int i = 1 ; i <= len_b ; i++) dp[0][i] = i;
for(int i = 1 ; i <= len_a ;i ++){
for(int j = 1 ; j <= len_b ;j++){
if(a[i - 1] == b[j - 1]) dp[i][j] = dp[i - 1][j - 1];
else dp[i][j] = min({dp[i - 1][j],dp[i][j - 1],dp[i - 1][j - 1]}) + 1;
}
}
cout << dp[len_a][len_b] << endl;
}
int main() {
IOS;
solve();
return 0;
}