DP问题从入门到精通2.2(线性DP,最短编辑距离)
DP入门到精通系列
- DP问题入门到精通1
- DP问题入门到精通2.1
- DP问题入门到精通3
- DP问题入门到精通4
- DP问题从入门到精通5
dp问题的难点到底是什么呢?
我认为是如何写出dp的更新方式,还有如何去对dp方程初始化。
相信很多人都有这样的做题经历,dp方程是对的,但就是少了个dp[0]=1,或者dp[0][i]=1(i取值从0到n)。
而这两个问题方法去解决,首先如何初始化,对应的就是状态表示,也就是我们如何去思考这道题的方式,我们可以通过状态表示去推导我们将要如何初始化,然后就是状态计算,状态计算对应的就是集合的划分——你是如何对给你所表示的状态分类的?而这个分类在线性dp中通常都是针对最后一个选与不选。通过对不同的分类取max,min等操作,就可以得到答案。
那么利用下面的题目,我就和大家分享一下我是怎么去思考的(思路来源acwing):
最短编辑距离
给定两个字符串 A 和 B,现在要将 A 经过若干操作变为 B,可进行的操作有:
- 删除–将字符串 A 中的某个字符删除。
- 插入–在字符串 A 的某个位置插入某个字符。
- 替换–将字符串 A 中的某个字符替换为另一个字符。
现在请你求出,将 A变为 B 至少需要进行多少次操作。
这道题也是比较经典的线性dp的问题,由之前对最长公共子序列(DP问题从入门到精通2.1(线性DP))的求解我们可以知道面对两个子序列的时候,我们可以选择从二维的角度去分析,所以我们可以很容易的想到我们的状态表示:以 i 结尾的子序列变成以 j 结尾的子序列所需要的最少的操作。这就是我们的状态方程f[ i ][ j ]的含义,那么状态计算呢?
由图我们看出来,我们总共由三个状态,分别对应删增改:
状态1删除,对应i-1,j 意思就是想让长度为 i 的子序列变为 j 的,同时我们发现长度i - 1 和 j 已经匹配了,那么我们只需要把长度为i 的第 i 个删除就可以了同时操作数+1。
状态2我们可以发现长度i 和 j-1 已经匹配了,那么想让 i 和 j 匹配只要在 i 后面加上 j 就可以了同时操作数+1。
状态3,这个状态分为两种情况,就是以 i 结尾的和以 j 结尾的子序列,前 i -1和 j-1 都已经匹配了,但 i 和 j 不相等,那么就要把 i 改掉,同时操作数+1。第二种情况是前 i -1和 j-1 都已经匹配了,但 i 和 j 相等,那么就不需要+1了。
现在状态计算对应的集合划分已经完成了,已经可以对dp方程做更新了,那么怎么初始化呢?开头我们说过,初始化其实就跟我们的状态表示有关,我们的状态表示是:
以 i 结尾的子序列变成以 j 结尾的子序列所需要的最少的操作。
那么如果把以 0 结尾第一个序列的变成以 j 结尾的第二个序列就只能用增,且最少的操作数与 j 的长度有关 :
for(int j=1;j<=m;j++)f[0][j]=j;
同理,如果把以 i 结尾第一个序列的变成以0结尾的第二个序列就只能用删,且最少的操作数与 i 的长度有关 :
for(int i=1;i<=n;i++)f[i][0]=i;
好了那么万事俱备,我们开始写最短编辑距离的代码:
const int N = 1010;
string a,b;int n,m;
int f[N][N];int main()
{cin>>n>>a>>m>>b;for(int i=1;i<=m;i++)f[0][i]=i;//初始化for(int i=1;i<=n;i++)f[i][0]=i;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);//前两个状态取minif(a[i-1]==b[j-1])f[i][j]=min(f[i][j],f[i-1][j-1]);//第三个状态取和两种情况分别取minelse f[i][j]=min(f[i][j],f[i-1][j-1]+1);}cout<<f[n][m];return 0;
}
编辑距离
给定 n 个长度不超过 10 的字符串以及 m 次询问,每次询问给出一个字符串和一个操作次数上限。
对于每次询问,请你求出给定的 n 个字符串中有多少个字符串可以在上限操作次数内经过操作变成询问给出的字符串。
每个对字符串进行的单个字符的插入、删除或替换算作一次操作。
输入格式
第一行包含两个整数 n 和 m。
接下来 n 行,每行包含一个字符串,表示给定的字符串。
再接下来 m 行,每行包含一个字符串和一个整数,表示一次询问。
字符串中只包含小写字母,且长度均不超过 10。
输出格式
输出共 m 行,每行输出一个整数作为结果,表示一次询问中满足条件的字符串个数。
由题意可知,编辑距离就是一道最短编辑距离的多次应用,所以直接上代码:
const int N =11;
int f[N][N];
string b;
int n,m;int cmp(string a,string b)
{int k=a.size(),l=b.size();for(int i=1;i<=l;i++)f[0][i]=i;for(int i=1;i<=k;i++)f[i][0]=i;for(int i=1;i<=k;i++)for(int j=1;j<=l;j++){f[i][j]=min(f[i-1][j]+1,f[i][j-1]+1);if(a[i-1]==b[j-1])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);}return f[k][l];
}int main()
{cin>>n>>m;vector<string> a(n,string(n,0));for(int i=0;i<n;i++)cin>>a[i];while(m--){ int limt,res=0;;cin>>b;cin>>limt;for(int i=0;i<n;i++)if(cmp(a[i],b)<=limt) res++;cout<<res<<endl;}return 0;
}
线性DP完结(可能)
由这个最短编辑距离可以说是体现了绝大部分dp问题的本质,只要写出状态表示和状态计算,这道dp题目就离ac不远了,以上就是我从acwing中学习的一点心得把,真心希望可以帮到大家
DP问题从入门到精通2.2(线性DP,最短编辑距离)相关推荐
- Linux从入门到精通系列之线性表链式存储结构-单链表原理解析
前言 线性表的链式存储结构的特点就是用一组任意的存储单元存储线性表的数据元素,这组存储单元可以在内存中未被占用的任意位置. 比起顺序存储结构每个元素只需要存储一个位置就可以了.现在链式存储结构中,除了 ...
- ExMobi®从入门到精通
ExMobi®从入门到精通 本书电子版和示例代码请访问GIT仓库: https://github.com/nandy007/ExMobiBeginnerBook ExMobi门户:http://www ...
- FPGA从入门到精通(8)-BRAM
所使用EDA软件:VIVADO2018.3 FPGA型号:xc7a35tcsg325-2 很久没写了,随便写一篇BRAM的吧.说到BRAM ,很多人都喜欢拿它来DRAM比较 ,两者都有啥优缺点,其实我 ...
- java从入门到精通_想要开始学java?你要的java从入门到精通布列如下!
java从入门到精通,让我来告诉你! 毫无疑问,java是当下最火的编程语言之一.对于许多未曾涉足计算机编程的领域「小白」来说,深入地掌握java看似是一件十分困难的事.其实,只要掌握了科学的学习方法 ...
- 虚幻引擎5(UE5)实时VFX游戏特效制作入门到精通
UE5 Niagara学习教程 课程获取:虚幻引擎5(UE5)实时VFX游戏特效制作入门到精通-云桥网 你会学到什么 我将通过创建各种各样的实时效果来教你虚幻引擎中强大的粒子系统. 我们将从简单的基 ...
- Revit:从入门到精通学习教程
流派:电子学习| MP4 |视频:h264,1280×720 |音频:AAC,48.0 KHz 语言:英语+中英文字幕(根据原英文字幕机译更准确) |大小:8.07 GB |时长:12h 16m Re ...
- 《Java 开发从入门到精通》—— 2.2 编写第一段Java程序
本节书摘来异步社区<Java 开发从入门到精通>一书中的第2章,第2.2节,作者: 扶松柏 , 陈小玉,更多章节内容可以访问云栖社区"异步社区"公众号查看. 2.2 编 ...
- meteor从入门到精通_我已经大规模运行Meteor一年了。 这就是我所学到的。
meteor从入门到精通 by Elie Steinbock 埃莉·斯坦博克(Elie Steinbock) 我已经大规模运行Meteor一年了. 这就是我所学到的. (I've been runni ...
- Java学习从入门到精通的学习建议
想要学好java技术,首先打好基础很重要,不论学什么基础都是重中之重,学习Java更是如此.如:基础语法.核心类库.面向对象编程.异常.集合.IO流等基础如果学不好,那么后边更深入的语法也不容易学会. ...
最新文章
- AI一分钟 | 特斯拉做空者频频“找茬”;自动驾驶汽车事故调查:人为是主因...
- 还找不到想要的文章吗?公众号搜索方法大全
- cmd查看python版本-在cmd中查看python的安装路径方法
- 块级元素和行内元素的区别
- 如何解决ORA-04031错误
- VHDL 语法小点(1)
- 1000道Python题库系列分享20(43道填空与判断题)
- Android RecyclerView实现长按弹出PopupMenu菜单
- 指针 是否相同_【变电小课堂】MF47指针式万用表操作指南
- word毕业论文导出高清pdf
- Linux-C 文件操作
- unity 走马灯packageManager
- 我的数据库是半瓶子水的水平
- MacOS启动台(launchpad)缺少应用软件图标
- Problem_1 小鸡啄米
- 语音识别(ASR)论文优选:Icassp 2022 M2MeT方案总结
- java中整数的整数次方_数值的整数次方java
- [Hector学习笔记]GNSS时间序列处理软件Hector使用备忘(批处理脚本)
- Private Set Intersection(PSI)
- 百度网盘取消自动续费(详细过程)
热门文章
- ffmpeg基础库编程开发.pdf
- Linux命令集(Linux文件管理命令--rm指令篇)
- python中使用scipy.optimize.leastsq进行球面、圆柱面、平面拟合
- synchronized和ReentrantLock区别浅析 (转载地址:http://blog.csdn.net/zmx729618/article/details/51594166)
- oracle 10g指定ocr位置,oracle 10g cluster 如何替换ocr主文件 (crs online状态)
- 解决鼠标右键点击后菜单延迟现象
- 越狱第三季第6集在线观看
- IBM站一个网页到底包含了多少技术
- ibm cloud_使IBM Cloud成为您选择平台的十大理由
- android 两种颜色融合,Android OpenGLES2.0(十八)——轻松搞定Blend颜色混合