动态规划——最长公共子序列

最长公共子序列算法
本文介绍如何使用动态规划解决最长公共子序列问题,包括非连续和连续子序列的求解方法,并提供详细的实现代码。

      两个序列的最长公共子序LCS(Longest Common Length)的每个字符可以不连续,X=<A, B, C, B, D, A, B>,Y=<B, D, C, A, B, A>,那么它们的最长公共子序列为<B, C, B, A>。这是一个经典的动态规划问题,着手点还是找到最精髓的状态转移方程。假设X,Y两个序列的前i,j个位置的最大子序列已经找到为r[i][j](自底往上),那么X[i] 与Y[j+1]的LCS就只要考虑一下两种情况:X[i] =Y[j+1] 和X[i] !=Y[j+1] ;Xi=Yj ,那么最长公共序列为MaxLen(Xi-1 , Yj-1) + 1;Xi !=Yj ,那么最长公共序列为MaxLen(Xi-1 ,Yj)和MaxLen(Xi ,Yj-1)中的最大值,具体如下:

根据下面的表格可以看出,每一列的数字最多增加1(当找到一个相同符号),一个字母只有当它前面的字母找到匹配时,它的增加才可能成为主路径。最后结果一定会累加到最后一个表格中




如果要寻找两个序列的最长公共子串,即连续相等的子序列,看起来有点麻烦,但只需将上面的状态方程X[i] !=Y[j]改为c[i,j]=0即可。



     这个图跟上面的图的区别就在于没有水平路径,只有斜对角线上相等的元素才能加1,其实就是要连续匹配的元素(i, j)与(i+1, j+1)才满足要求。



代码如下:

int LCS_dp(string a, string b, int l1, int l2)
{
	int r[100][100]={0};
	int len=0;
	int i,j;
	for(i=0; i<l1;i++)
	{
		for(j=0; j<l2; j++)
		{
			if(a[i] == b[j])
				r[i+1][j+1]=r[i][j]+1;
			else
				r[i+1][j+1]=max(r[i][j+1], r[i+1][j]);									
                        /*else 
				r[i+1][j+1]=0;	*/   //这个是求连续子串的状态方程,直接清零
			
			if(r[i+1][j+1] > len)  len=r[i+1][j+1];
		}
	}
	return len;																				
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值