• ACwing 902


    给定两个字符串A和B,现在要将A经过若干操作变为B,可进行的操作有:

    • 删除–将字符串A中的某个字符删除。
    • 插入–在字符串A的某个位置插入某个字符。
    • 替换–将字符串A中的某个字符替换为另一个字符。

    现在请你求出,将A变为B至少需要进行多少次操作。

    输入格式

    第一行包含整数n,表示字符串A的长度。

    第二行包含一个长度为n的字符串A。

    第三行包含整数m,表示字符串B的长度。

    第四行包含一个长度为m的字符串B。

    字符串中均只包含大写字母。

    输出格式

    输出一个整数,表示最少操作次数。

    数据范围

    1 ≤ n,m ≤ 1000

    输入样例:

    10
    AGTCTGACGC
    11
    AGTAAGTAGGC

    输出样例:

    4

    题目大意:

    给出两个字符串的长度和两个字符串AB,可以对串A进行三种操作:增、删、改,输出串A到串B至少需要几次操作。

    解题思路:

    线性dp问题,dp问题从两方面考虑

    • 状态表示: 用两维去表示状态,f(i, j) 表示字符串 A 的前 i 个字符变化到字符串 B 的前 j 个字符所需的操作数, 本题要求的是最小值,所以f[i][j] 表示为A串的前 i 个字符变化到 B串的前 j 个字符所需的最小操作数。
    • 状态计算: 考虑怎么转移到f[i][j],有增,删,改三种操作,考虑增加,即考虑f[i][j - 1] 串A的前 i 个字符变化到 B 的j - 1 个字符的最小操作数,A前 i 个字符已经和Bj - 1匹配,那么增加一个字符bj后才能做到ai bj 匹配。再考虑删除,先上状态:f[i - 1][j] + 1 删除之前,必须考虑a[i - 1] 已经和 b[j] 匹配上,才能实现删除一个字符匹配成功。而修改操作:考虑a[i - 1] 和 b[j - 1] 已经匹配,然后判断a[i] == b[j] 考虑是否 + 1。

    Code:

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    
    using namespace std;
    
    const int N = 1e3 + 10;
    
    int n, m;
    char a[N], b[N];
    int f[N][N];
    
    int main()
    {
        scanf("%d%s%d%s", &n, a + 1, &m, b + 1);
        
        for (int i = 1; i <= n; i ++) f[i][0] = i;//初始化很重要
        for (int i = 1; i <= m; i ++) f[0][i] = i;
        
        for (int i = 1; i <= n; i ++)
            for (int j = 1; j <= m; j ++)
            {
                f[i][j] = min(f[i - 1][j], f[i][j - 1]) + 1;
                f[i][j] = min(f[i][j], f[i - 1][j - 1] + (a[i] != b[j]));
            }
        
        cout << f[n][m] << endl;
        
        return 0;
    }
    
  • 相关阅读:
    Jenkins安装及配置
    数据库命令扩展
    常用的数据库命令
    如何使用NiFi等构建IIoT系统
    云计算之概念——IaaS、SaaS、PaaS、Daas
    emqx的一个配置参数
    利用jsoup抓取网页图片
    nohup使用
    jsoup的使用
    java知识点链接
  • 原文地址:https://www.cnblogs.com/Hayasaka/p/14294130.html
Copyright © 2020-2023  润新知