有 A=a1a2a3„am,B=b1b2b3„bn 两个字符串(均为小写字母)现在要通过以下操作将 A
或 A 的一个后缀修改为 B:
1. 删除 删除掉 A 中的某一个字符。
2. 添加 将某一个字符添加到 A 中任意位置。
3. 替换 将 A 中某一字符替换为另一个。
求出最小操作次数
第一行为字符串 A。第二行为字符串 B(长度均不超过 1000)。
题目描述很有让人爆搜的想法啊,看到数据,嗯,绝望了。
以这种大小明显不是爆搜可以解决的吧,看起来很像dp的样子呢,试试吧(重点我也没想到别的算法)
之前我看一个大佬的博客,大佬表示只要想通怎么去做就可以了,他每一步是怎么实现的不重要,仔细去想反而会更加迷糊。
(我上午试图仔细想想,试图把一些奇怪的问题都想出来,但我发现越来越乱,其实只要知道他让我们干什么,我们该怎么干就好了,具体会发生什么我们不需要知道。)
本来我是在写后缀的,dp[i][j]=a的后i个数要多少步才能变成b的前j个数。
但是这个代码有点太恶心人了,我脑子有点乱,感觉这不是什么好主意……
我就改了一下主意:dp[i][j]=a的前i个数要多少步才能变成b的前j个数。
大家想想啊,虽然这个是前缀,但如果前缀没什么用是不是可以忽略掉,竟然这样的话,代码清晰,思路也清晰就不是事了。
emm,写完了,但出了一点小问题。
大家都知道字符串第一个字符的下表是0,竟然是0的话,那么就不能出现什么dp[x-1]之类的东西,会崩掉的。
这不是很大的事情,但我处理的有些繁琐,导致自己出的一个数据一直过不去,还不知道为啥。
然后就来了一波操作,让输入的字符串下标整体向后移动了一下。
减少了奇怪的操作,问题解决了。
虽然我不知道为什么会有问题,但我知道是哪里出了问题,替代掉它就可以了。
一些奇怪的问题解决了,接下来是正经的dp了。
通过前面的说法,dp[i][j]表示a的前i个字符改变成b的前j个字符的次数。
我们可以得到一个简单好想的状态转化方程,就像新手礼包一样。dp[i][j]=min(dp[i-1][j-1]+bj,min(dp[i-1][j]+1,dp[i][j-1]));
emm,有点长,同学们可能看不懂,简单解释一下,我们把他分开,变成3部分
第一部分:dp[i-1][j-1]+bj
bj的意思是新加进来的两个字符是否相等,相等就抵消了嘛,不想等还要处理……
这一步还包含替换操作。
相等的话bj就是0,不相等就是1咯。
第二部分:dp[i-1][j]+1
第三部分:dp[i][j-1]+1
这2部分对应j-1和i-1的情况,我们会发现这两个有个共同点,就是现在的j比刚才的i多1个,所以我们只要在之前的里面再加上一个就可以解决了。
3个操作都想出来了,该放个代码了
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#include<cstring>
using namespace std;
long long dp[1005][1005],ac,bc,bj;
char a[1005],b[1005];
int main()
{
freopen("str.in","r",stdin);
freopen("str.out","w",stdout);
cin>>a+1>>b+1;
ac=strlen(a+1);
bc=strlen(b+1);
for(int i=1;i<=ac;i++)//dp不初始化,考完两行泪啊。
{
dp[i][0]=0;
}
for(int i=1;i<=bc;i++)
{
dp[0][i]=i;
}
for(int i=1;i<=ac;i++)//简单和谐的代码
{
for(int j=1;j<=bc;j++)
{
if(a[i]==b[j])
{
bj=0;
}else
{
bj=1;
}
dp[i][j]=min(dp[i-1][j-1]+bj,min(dp[i][j-1]+1,dp[i-1][j]+1));
}
}
cout<<dp[ac][bc]<<endl;
return 0;
}

思路写了这么多,代码只有40行(如果我不是这个码风可能还短),dp这种东西想起来有点难,写起来还是挺好写的。

附加:奉劝你们不要深究,明白为什么这么写就好,硬要想中间发生了什么会让脑子很乱(可能只有我这样),实在想不明白可以私下问我。看不看的见就随缘吧。

T4 字符串的修改 题解的更多相关文章

  1. 【2014广州市选day1】JZOJ2020年9月12日提高B组T4 字符串距离

    [2014广州市选day1]JZOJ2020年9月12日提高B组T4 字符串距离 题目 Description 给出两个由小写字母组成的字符串 X 和Y ,我们需要算出两个字符串的距离,定义如下: 1 ...

  2. Python字符串的修改以及传参

    前两天去面试web developer,面试官提出一个问题,用JavaScript或者Python实现字符串反转,我选择了Python,然后写出了代码(错误的): #!/usr/bin/env pyt ...

  3. P141 实战练习——字符串(修改后)

    1.在项目中创建Number类,判断字符串“mingrikejijavabu”中字符‘i’出现了几次,并将结果输出. 方法一: // String str="mingrikejijavabu ...

  4. Q: 字符串的修改

    题目描述 怎么样,前面的题还可以吧~ 依旧是字符串处理,设A和B是两个字符串.我们要用最少的字符操作次数,将字符串A转换为字符串B.这里所说的字符操作共有三种: 1. 删除一个字符: 2. 插入一个字 ...

  5. C++string中有关字符串内容修改和替换的函数浅析

    1.assign() 原型: //string (1) basic_string& assign (const basic_string& str); //substring (2) ...

  6. zf-关于即将过期提示字符串的修改

    Struts2中的 addFieldError(str1,str2); 自带输出 str1= [str2] 这样子是自带输出的 但是如果 要把=[]替换掉怎么办呢 当时想的很复杂,现在知道了,其实很简 ...

  7. FZU 2280 Magic(字符串Hash)题解

    题意:给你n个字符串,每个字符串有一个值w,有q次询问,一共两种操作:一是“1 x y”表示把第x个串的w变为y:二是“2 x”,输出第x个串能放几次魔法.放魔法的条件是这样:用串x放魔法,如果在1~ ...

  8. 模拟、字符串--P1042 乒乓球 题解

    P1042 乒乓球 字符串string的基本使用 #include <iostream> #include <algorithm> #include <map> # ...

  9. 力扣(LeetCode)验证回文字符串II 个人题解

    给定一个非空字符串 s,最多删除一个字符.判断是否能成为回文字符串. 示例 1: 输入: "aba" 输出: True 示例 2: 输入: "abca" 输出: ...

随机推荐

  1. Linux 半连接队列,全连接队列

    socket 中 listen api中参数backlog指定的是 全队列大小 accept api是从全队列中获取, 没有就阻塞了, 直到有新连接进来. listen中指定的值大小,有一个最大上限, ...

  2. 【原创】强撸基于 .NET 的 Redis Cluster 集群访问组件

    Hello 大家好,我是TANZAME,我们又见面了.今天我们来聊聊怎么手撸一个 Redis Cluster 集群客户端,纯手工有干货,您细品. 随着业务增长,线上环境的QPS暴增,自然而然将当前的单 ...

  3. cron计划任务

    格式 crontab -e [-u 用户名] ##编辑:注意,每项工作都是一行. crontab -l [-u 用户名] ##查看 crontab -r [-u 用户名] #清除 分 时 日 月 周 ...

  4. elasticsearch中query和filter的区别

    参考博客来自: https://mp.weixin.qq.com/s/tiiveCW3W-oDIgxvlwsmXA?utm_medium=hao.caibaojian.com&utm_sour ...

  5. Web安全之验证码绕过

    一,验证码绕过(on client) 首先让burpsuite处于抓包状态,打开pikachu的验证码绕过(on client)随意输入账号和密码,验证码先不输入,点击login,会提示验证码错误 然 ...

  6. vs code 初始化vue项目框架

    1.首先安装npm组件  下载地址:https://nodejs.org/en/ 安装完 2.配置环境变量 3.验证是否成功 node -v npm -v 4.替换npm 输入npm install ...

  7. 深入理解JVM(③)虚拟机的类加载器(双亲委派模型)

    前言 先解释一下什么是类加载器,通过一个类的全限定名来获取描述该类的二进制字节流,在虚拟机中实现这个动作的代码被称为"类加载器(Class Loader)". 类与类加载器 类加载 ...

  8. Linux hostname主机名配置文件/etc/hosts详解

    这篇文章为大家介绍linux hostname主机名配置文件/etc/hosts,包括主机名的用途.配置文件的操作方法等,有需要的朋友,可以参考下 1.什么是Linux主机名 无论在局域网还是INTE ...

  9. 如何在linux下安装tomcat服务器

    linux作为现在比较主流的服务器操作系统,使用的机器广泛,安全稳定.tomcat作为应用容器当然可以有linux版本的tomcat.在linux上安装tomcat的方式也很简单,只需要运行脚本基本配 ...

  10. .NET 开源工作流: Slickflow流程引擎高级开发(七)--消息队列(RabbitMQ)的集成使用

    前言:工作流流程过程中,除了正常的人工审批类型的节点外,事件类型的节点处理也尤为重要.比如比较常见的事件类型的节点有:Timer/Message/Signal等.本文重点阐述消息类型的节点处理,以及实 ...