动态规划与序列问题

本文探讨了如何利用动态规划方法处理序列问题,通过一个关键公式:当xm=yn时,LCS(X,Y)=xm+LCS(Xm-1,Yn-1);若xm≠yn,LCS(X,Y)=max{LCS(Xm-1,Y), LCS(X,Yn-1)},揭示了解决这类问题的核心思路。" 89496741,8330275,H5调用USB外接摄像头实现,"['H5', '摄像头', '前端开发']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.最长公共子串
问题描述
	如果字符串一的所有字符按其在字符串中的顺序出现在另外一个字符串二中,则字符串一称之为字符串二的子串。注意,并不要求子串(字符串一)的字符必须连续出现在字符串二中。
动态规划
	使用dp[i][j]表示 以x[i]和y[j]结尾的最长公共子串的长度,因为要求子串连续,所以对于X[i]与Y[j]来讲,它们要么与之前的公共子串构成新的公共子串;要么就是不构成公共子串。故状态转移方程 X[i] == Y[j],dp[i][j] = dp[i-1][j-1] + 1 X[i] != Y[j],dp[i][j] = 0 对于初始化,i==0或者j==0,如果X[i] == Y[j],dp[i][j] = 1;否则dp[i][j] = 0。这样的处理跟连续子数组最大和有点类似,只是连续子数组子和是当dp[i]<0时执行dp[i]=0。

2.最长公共子序列(LCS)
 
问题描述
	最长公共子序列就是寻找两个给定序列的子序列,该子序列在两个序列中以相同的顺序出现,但是不必要是连续的。
动态规划求解
	使用动态规划求解这个问题,先寻找最优子结构。设X=<x1,x2,…,xm>和Y=<y1,y2,…,yn>为两个序列,LCS(X,Y)表示X和Y的一个最长公共子序列,可以看出
  1. 如果xm=yn,则LCS ( X,Y ) = xm + LCS ( Xm-1,Yn-1 )。
  1. 如果xm!=yn,则LCS( X,Y )= max{ LCS ( Xm-1, Y ), LCS ( X, Yn-1 ) }
LCS问题也具有重叠子问题性质:为找出X和Y的一个LCS,可能需要找X和Yn-1的一个LCS以及Xm-1和Y的一个LCS。但这两个子问题都包含着找Xm-1和Yn-1的一个LCS,等等。 为了找到最长的LCS,我们定义dp[i][j]记录序列LCS的长度,合法状态的初始值为当序列X的长度为0或Y的长度为0,公共子序列LCS长度为0,即dp[i][j]=0,所以用i和j分别表示序列X的长度和序列Y的长度,状态转移方程为dp[i][j] = 0 如果i=0或j=0dp[i][j] = dp[i-1][j-1] + 1 如果X[i-1] = Y[i-1]dp[i][j] = max{ dp[i-1][j], dp[i][j-1] } 如果X[i-1] != Y[i-1]求出了最长公共子序列的长度后,输出LCS就是输出dp的最优方案了,既可以用一个额外的矩阵存储路径,也可以直接根据状态转移矩阵倒推最优方案。 3.字符串编辑距离   问题描述 字符串编辑距离又叫字符串相似度,编辑距离就是将两个不同的字符串变成相同字符串所需要操作的次数的最小值。而这些操作只有以下三种: 1)修改一个字符 2)增加一个字符 3)删除一个字符   寻找子问题时,我们完全可以像分析最长公共子序列那样分析这个问题,都是“从后向前”看,假设有两个串X=abcdaex,Y=fdfax,它们的最后一个字符是相同的,只要计算X[1,…,6]=abcdae和Y[1,…,4]=fdfa的距离就可以了;但是如果两个串的最后一个字符不相同,那么就可以进行如下的操作来达到目的(xlen和ylen是X串和Y串的长度):   1.一步操作之后,再计算X[1,…,xlen-1]和Y[1,…ylen]的距离。这个操作可以是删除X的最后一个字符,也可以是增加X串的最后一个字符到Y串的最后字符之后 2.一步操作之后,再计算X[1,…,xlen]和Y[1,…ylen-1]的距离。这个操作与情况1类似,反过来而已 3.一步操作之后,再计算X[1,…,xlen-1]和Y[1,…ylen-1]的距离。这个操作可以是修改X串的最后有一个字符为Y串的最后一个字符,后者修改Y的变为X的最后一个字符,使得二者相同。     dp[i][j]中的i和j表示串X和Y的长度,其中,如果某一个串的长度为0,则编辑距离就是另一个串的长度,这很容易理解。状态转移方程为   1.dp[i][j] = 0  如果i=0 & j=0 2.dp[i][j] = xlen | ylen  如果j=0 | i=0 3.dp[i][j] = dp[i-1][j-1]  如果X[i-1] = Y[i-1] 4.dp[i][j] = 1 + min{ dp[i-1][j], dp[i][j-1], dp[i-1][j-1] }  如果X[i-1] != Y[i-1]   4.最大连续子序列和 最大子序列是要找出由数组成的一维数组中和最大的连续子序列。比如{5,-3,4,2}的最大子序列就是 {5,-3,4,2},它的和是8,达到最大;而 {5,-6,4,2}的最大子序列是{4,2},它的和是6。你已经看出来了,找最大子序列的方法很简单,只要前i项的和还没有小于0那么子序列就一直向后扩展,否则丢弃之前的子序列开始新的子序列,同时我们要记下各个子序列的和,最后找到和最大的子序列。

5.最长递增子序列(LIS)
像LCS一样,从后向前分析,很容易想到,第i个元素之前的最长递增子序列的长度要么是1(单独成一个序列),要么就是第i-1个元素之前的最长递增子序列加1,可以有状态方程:
LIS[i] = max{1,LIS[k]+1},其中,对于任意的k<=i-1,arr[i] > arr[k],这样arr[i]才能在arr[k]的基础上构成一个新的递增子序列。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值