我是靠谱客的博主 酷酷鸵鸟,最近开发中收集的这篇文章主要介绍关于二维DP————站上巨人的肩膀,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Python微信订餐小程序课程视频

https://edu.csdn.net/course/detail/36074

Python实战量化交易理财系统

https://edu.csdn.net/course/detail/35475
意匠惨淡经营中ing,

语不惊人死不休…

前几天学了DP,做了个简单的整理,记录了关于DP的一些概念之类的,今天记录一下刚学的一个类型

————关于二维DP

那建立二维数组主要是干嘛用的呢???其实就是是记录两个状态,(我也不是很清楚),然后再递推

直接上题吧

T1 、最长公共子序列:

好像有印象,之前做过一道类似的题,叫做最长上升子串,需要注意的是,这俩可不是很一样,人家子序列可以不连续,只要是相对顺序不改变就行,但是子串必须是连续的,针对这种题,我们联想起原来做题时想的状态转移方程,再加以改动就可以了:

f[i][j] 还是表示数组a的前i个元素和b数组的前j个元素能组成的最长子串的长度

那很容易以相同的方法联想到子序列,还是分情况讨论:

1、x[i]==y[j]时:f[i][j]=f[i-1][j-1]+1 (就是它们如果相等,长度就是不加上它们时组成的子串的长+1)

2、x[i]!=y[j]时:

1 2 3 4 5  和  2 3 5,这两个子串在 i=4,j=2 的时候,由于a[i]!=b[j],加上它们俩和不加他们俩其实并不影响最长长度,所以i和j对应的他们以前这些元素(不包括i,j)能组成的最长长度其实和它们现在(包括i,j)能组成的长度是相同的(不必+1),所以当a[i]!=b[j],它们对应的长度可以是f[i-1][j],也可以是f[i][j-1],取个max就好

再考虑边界,当一个字符串有0个元素时,它们的f[i][j]永远是0,所以f[0][j]=0 ,f[i][0]=0

代码如下:

 1 #include
 2 #include
 3 #include
 4 #include
 5 using namespace std;
 6 int f[1001][1001];
 7 char x[1001],y[1001];
 8 int maxn;
 9 int main()
10 {
11 cin>>x;
12 cin>>y;
13 int m=strlen(x);
14 int n=strlen(y);
15 for(int i=0;i)
16 for(int j=0;j)
17  {
18 f[i][0]=0;
19 f[0][j]=0;
20  }
21 for(int i=1;i<=m;i++)
22  {
23 for(int j=1;j<=n;j++)
24  {
25 if(x[i-1]==y[j-1]) f[i][j]=f[i-1][j-1]+1;//人家是从0开始纳入的,所以这里要-1
26 else f[i][j]=max(f[i-1][j],f[i][j-1]);
27 maxn=maxn>f[i][j]? maxn:f[i][j]; 
28  }
29  } 
30 printf("%d",maxn);
31 return 0;
32 }

T2、编辑距离:

题意:有两个字符串,现在有三种操作:1、删除一个字符,2、插入一个字符,3、将一个字符改成另一个字符,现在要求要么花最少的字符操作次数,将字符串A转成B(只能操作A串)。

还是先设变量,f[i][j]表示把x[1i]变为y[ij]的最少操作次数,现在的目标就是求出状态转移方程:

还还还是分两种情况讨论:

x[i]==y[j] 时,那我们就可以不对它们进行操作了,也就是说我们直接让f[i][j]=f[i-1][j-1]

当 **x[i]!=y[j]**时,我们有三种操作,需要分别求出他们的状态转移方程

1、删除 x[i],那就是上一次的操作次数再加上1,即 f[i][j]=f[i-1][j]+1

2、给x[i]插入新字符:那就是相当于给y[j]删去一位,即 f[i][j]=f[i][j-1]+1

3、将x[i]变为y[j]:目前a数组的前i位和b数组的前j

最后

以上就是酷酷鸵鸟为你收集整理的关于二维DP————站上巨人的肩膀的全部内容,希望文章能够帮你解决关于二维DP————站上巨人的肩膀所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(28)

评论列表共有 0 条评论

立即
投稿
返回
顶部