线性dp:最短编辑距离

题目链接:https://www.acwing.com/problem/content/904/
题意:给定两个字符串A和B,现在要将A经过若干操作变为B,可进行的操作有:
1. 删除–将字符串A中的某个字符删除。
2. 插入–在字符串A的某个位置插入某个字符。
3. 替换–将字符串A中的某个字符替换为另一个字符。
现在请你求出,将A变为B至少需要进行多少次操作。
数据范围
1≤n,m≤1000
输入样例:
10
AGTCTGACGC
11
AGTAAGTAGGC
输出样例:
4
思路:时间复杂度O(n²)

  • 状态表示:1.集合:所有将a[1 ~ i]变成b[1 ~ j] 的操作方式;2属性:这些操作方式的最小值
  • 状态计算:无非三种操作: (1) 删:删除a [ i ] 试得a[1 ~ i - 1] = b[1 ~ j ],即 f [i - 1 , j ] + 1 ; (2) 添加一个a [ i ] 使得 a[1 ~ i] = b [ j ],即f[ i , j - 1] + 1; (3) 修改a [ i ] 使得a[1 ~ i] = b [ j ],即f[ i - 1 , j - 1] + 1.
    代码实现:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
const int MAXN=1005;
int n, m;
char a[MAXN],b[MAXN];
int f[MAXN][MAXN];
int main()
{
    scanf("%d%s",&n, a + 1);
    scanf("%d%s",&m, b + 1);
    for(int i = 0; i <= m; i ++ ) f[0][i] = i;//如果a串为0的话就需要添加i的字母来和b的前i个字母匹配,所有初始化一下
    for(int i = 1; i <= n; i ++ ) f[i][0] = i;//同理如果b为0的话,需要初始化一下
    for(int i = 1; i <= n; i ++ ){
        for(int j = 1; j <= m; j ++ ){
            f[i][j] = min(f[i - 1][j] + 1, f[i][j - 1] + 1);
            if(a[i] == b[j]) f[i][j] = min(f[i][j], f[i - 1][j - 1]);
            else f[i][j] = min(f[i][j], f[i - 1][j - 1] + 1);
        }
    }
    printf("%d\n",f[n][m]);//指把a的前n个字母变成b的前m个字母的最小步骤
    return 0;
}

发布了61 篇原创文章 · 获赞 0 · 访问量 979

猜你喜欢

转载自blog.csdn.net/Satur9/article/details/104034669