最长公共子序列问题(动态规划,含可运行代码)

一、最长公共子序列模型

(1) 存在两个字符串序列:X={x1,x2,...,xm}, Z={z1,z2,...zk}

(2)存在一个严格递增下标序列{i1,i2,..,ik}使得对于所有j=1,2,...,k有:zk=xij

(3)X和Y的最长公共子序列

        1) 序列X,Y

        2) 序列Z既是X的子序列又是Y的子序列,称Z是序列X和Y的最长公共子序列

(4)目标问题描述

          给定两个序列X={x1,x2,...,xm}和Y={y1,y2,...,yn},找出最长公共子序列

二、求解方法

1.蛮力搜索法(不推荐使用该方法)

   (1)列举A所有的2^{n}个子序列,对于每一个子序列在O(m)时间内来确定它是否也是B的子序列

    (2)时间复杂性是O(m2^{n}

2、反向分析法

    问题:Z={z1,z2,...,zk}是序列X={x1,x2,...,xm}和Y={y1,y2,...,yn}的最长公共子序列

    应用该方法求最长公共子序列应该具有如下三个性质:(最优子结构的性质)

         

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,针对你的问题,下面是最长公共子序列问题动态规划算法C代码实现: ```c #include <stdio.h> #include <string.h> #define MAX_LEN 100 int LCS(char *s1, char *s2) { int len1 = strlen(s1); int len2 = strlen(s2); int dp[MAX_LEN][MAX_LEN] = {0}; int i, j; for (i = 1; i <= len1; i++) { for (j = 1; j <= len2; j++) { if (s1[i - 1] == s2[j - 1]) { dp[i][j] = dp[i - 1][j - 1] + 1; } else { dp[i][j] = dp[i - 1][j] > dp[i][j - 1] ? dp[i - 1][j] : dp[i][j - 1]; } } } return dp[len1][len2]; } int main() { char *s1 = "ABCD"; char *s2 = "BD"; int length = LCS(s1, s2); printf("%d\n", length); return 0; } ``` 在代码实现中,我们利用动态规划的思想求解最长公共子序列问题。具体地,我们将问题划分为若干个子问题,并将已经得到的子问题的结果保存下来,以供后续计算使用。 针对输入的两个字符串s1和s2,我们首先获取它们的长度len1和len2。然后我们定义一个动态规划数组dp,其中dp[i][j]表示s1的前i个字符和s2的前j个字符之间的最长公共子序列的长度。初始时,我们将dp[0][0]设为0,表示空字符串之间的最长公共子序列长度为0;而将dp[0][j]和dp[i][0]都设为0,表示一个非空字符串和一个空字符串之间的最长公共子序列长度也为0。 接下来,我们采用双重循环的方式,遍历s1和s2的每个字符。如果当前s1的第i个字符和s2的第j个字符相等,则说明当前这个字符是它们所共有的,那么它就可以成为它们的最长公共子序列的一部分。此时,我们将dp[i][j]设为dp[i-1][j-1]+1。否则,说明当前这个字符不是它们所共有的,那么我们将在s1的前i-1个字符和s2的前j个字符之间找到一个最长公共子序列,或者在s1的前i个字符和s2的前j-1个字符之间找到一个最长公共子序列,然后取这两个最长公共子序列中的较长者作为它们的最长公共子序列长度。此时,我们将dp[i][j]设为dp[i-1][j]和dp[i][j-1]中的较大值。 最后,我们返回dp[len1][len2],即s1和s2的最长公共子序列长度。在本例中,我们以字符串"ABCD"和"BD"为例,求它们之间的最长公共子序列长度。运行以上代码,可以得到输出结果2,表明它们之间的最长公共子序列长度为2。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值