动态规划算法矩阵的计算

本文介绍了如何使用动态规划算法解决最长公共子序列(LCS)问题。通过分析问题,提出递归公式,当字符相等时,LCS长度加1;不等时,取上一行或左一列的较大值。遇到重复字符和分支情况时,给出了明确的处理策略,并结合源代码详细阐述了算法实现过程。
摘要由CSDN通过智能技术生成

一.问题分析

   求解LCS问题,不能使用暴力搜索方法。一个长度为n的序列拥有 2的n次方个子序列,它的时间复杂度是指数阶,太恐怖了。解决LCS问题,需要借助动态规划的思想。
 	动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。![动态规划算法设计图](https://img-blog.csdnimg.cn/20210623101413278.png)

p1表示X的前 i-1 个字符和Y的前 j 个字符的LCS的长度
p2表示X的前 i 个字符和Y的前 j-1 个字符的LCS的长度
p表示X的前 i-1 个字符和Y的前 j-1 个字符的LCS的长度
p0表示X的前 i 个字符和Y的前 j 个字符的LCS的长度
如果X的第 i 个字符和Y的第 j 个字符相等,则p0 = p + 1
如果X的第 i 个字符和Y的第 j 个字符不相等,则p0 = max(p1,p2)

二.遇到的问题及其解决方案

采用一个序列的第一个字符对照另一个序列中的字符,但是有可能出现重复的字符,进行多次重复的比对。递归方法,但仍然无法保留最长公共子序列的中间结果,所以可以借助LCS的的长度。首先利用递归公式,规则:如果横竖(i,j)对应的两个元素相等,该格子的值 = c[i-1,j-1] + 1。如果不等,取c[i-1,j] 和 c[i,j-1]的最大值,最后得到如下图:
推论图
然后依据上表逆推回去,
c[8][9]=5且S1[8]!=S2[9],所以倒推回去c[8][9]的值来源于c[8][8]的值(因为c[8][8]>c[7][9])。
c[8][8]= 5,且S1[8] = S2[8], 所以倒推回去,c[8][8]的值来源于c[7][7]。
以此类推,如果遇到S1[i] != S2[j],且c[i-1][j]=c[i][j-1],这种存在分支的情况,这里请都选择一个方向(之后遇到这样的情况,也选择相同的方向)。 例图如下:
反推图

源代码

#include<stdio.h>
#include<string.h>
int c[200][200];   //用c[i][j]记录X[i]与Y[j] 的LCS 的长度
int b[200][200];   //b[i][j]记录c[i][j]是通过哪一个子问题的值求得的,以决定搜索的方向
char f[200];
 
/*-----------------------分割线--------------------------------*/
 
/*取c[i-1][j]和c[i][j-1]的最大值,并记录c[i][j]是通过哪一个子问题的值求得的,以决定搜索的方向*/
int Max(int m,int n,int i,int j)
{
   
	if(m > n)
	{
   
		b[i][j] = -1;
		return m;
	}
	else
	{
   
		b
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值