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

题目描述

一个给定序列的子序列是在该序列中删去若干元素(也可以不删去)后得到的序列。例如Z=“BCDB” 就是X="ABCBDAB"的一个子序列,而Z=“CBBD"则不是X的子序列。 给定三个序列 X,Y和Z,如果Z既是X的一个子序列又是Y的一个子串,则称Z是X和Y的公共子序列。
例如X="ABCBDAB”,Y=BDCABA",则序列"BCA"即为X和Y的一个公共子序列,但不是X和Y的最长公共子序列(LCS),因为还有比它更长的公共子序列"BCBA"。事实上"BCBA"是X和Y的一个LCS ,"BDAB"也是一个LCS。 现输入两个序列X和Y,要求出X和Y的最长公共子序列。

输入格式

第1行:两个用字符串表示的序列X和Y。1<=X.size(),Y.size()<=1000,两个序列之间用1个空格分隔。序列均由大写字母组成。

输出格式

第1行:一个整数L,表示两个序列的最长公共子序列的长度。

解题思路

这题显然要用到动态规划
本题是动态规划的经典题目,我们便设f[i][j]为截至字符串X的第i个字符和字符串Y的第j个字符时,最长公共子序列的长度。

状态转移方程

那f[i]j[j]有两种情况:
(1)X[i]与Y[j]相同,则我们只需考虑f[i-1][j-1],再加1即可。即f[i][j]=f[i-1][j-1]+1
(2)X[i]与Y[j]不相同,则我们就看f[i-1][j]的值和f[i][j-1]的值,两者取最大值即可。即f[i][j]=max(f[i-1][j],f[i][j-1])
实现成代码:

if(x[i]==y[j]) f[i][j]=f[i-1][j-1]+1;
else f[i][j]=max(f[i-1][j],f[i][j-1]);

初始化

因为f[1][1]本身为0,定义在main函数外就自动初始化为0了,所以不用写 memset(f,0,sizeof(f)) 了。

循环次数

我们设len1为字符串X的长度,len2为字符串Y的长度,则i就从1循环到len1,j从1循环到len2
备注:本蒟蒻输入时是从1开始的,详细见下面的代码

完整代码:

#include<bits/stdc++.h>
using namespace std;
char x[1005],y[1005];
int f[1005][1005],a[1005];
int main()
{
	scanf("%s %s",x+1,y+1);
	int len1=strlen(x+1),len2=strlen(y+1);
	for(int i=1;i<=len1;i++)
	{
		for(int j=1;j<=len2;j++)
		{
			if(x[i]==y[j]) f[i][j]=f[i-1][j-1]+1;
			else f[i][j]=max(f[i-1][j],f[i][j-1]);
		}
	}
	printf("%d\n",f[len1][len2]);
	return 0;
}

这是本蒟蒻的第一篇博客,写得不好请见谅🙏。并且希望能帮到和我一样菜的蒟蒻程序猿们。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
最长公共子序列问题(Longest Common Subsequence,简称LCS)是指在两个序列找到一个最长共子序列,其一个序列的所有元素按原序列出现的顺序排列,而另一个序列的元素则不要求按原序列出现的顺序排列。 动态规划方法可以很好地解决LCS问题。设A和B是两个序列,LCS(A,B)表示A和B的最长公共子序列。则可以设计如下的状态转移方程: 当A和B的末尾元素相同时,LCS(A,B) = LCS(A-1,B-1) + 1。 当A和B的末尾元素不同时,LCS(A,B) = max(LCS(A-1,B), LCS(A,B-1))。 其,LCS(A-1,B-1)表示A和B的末尾元素相同时的情况,LCS(A-1,B)表示A的最后一个元素不在最长公共子序列,而B的最后一个元素在最长公共子序列的情况,LCS(A,B-1)表示B的最后一个元素不在最长公共子序列,而A的最后一个元素在最长公共子序列的情况。 根据这个状态转移方程,可以使用动态规划算法来求解LCS问题。具体方法是,构建一个二维数组dp,其dp[i][j]表示A前i个元素和B前j个元素的LCS。初始化dp[0][j]和dp[i][0]为0,然后按照上述状态转移方程进行递推,最终得到dp[lenA][lenB],其lenA和lenB分别表示A和B的长度。dp[lenA][lenB]即为A和B的最长公共子序列的长度。要找到具体的最长公共子序列,可以从dp[lenA][lenB]开始,按照状态转移方程反向推导出每个元素,即可得到最长公共子序列。 LCS问题是动态规划算法的经典应用之一,时间复杂度为O(n*m),其n和m分别为A和B的长度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值