算法设计-动态规划——最长公共子序列

本文介绍了如何使用动态规划算法解决最长公共子序列问题。通过详细分析和伪代码展示,阐述了动态规划的基本思路,以及在解决此类问题时如何记录和回溯解题过程。以字符串BDCABA和ABCBDAB为例,展示了如何找出它们的最长公共子序列BCBA。
摘要由CSDN通过智能技术生成

算法介绍

动态规划:

动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的(自底向上求解,底层的解可作为上层解的基础 )。

问题实例

问题描述:

题目:
给定两个字符串,求解这两个字符串的最长公共子序列(Longest Common Sequence)。
比如字符串1:BDCABA;字符串2:ABCBDAB
则这两个字符串的最长公共子序列长度为4,最长公共子序列是:BCBA

问题分析

对于动态规划的问题我们一般使用数组记录小的分组得到的结果。在该题中我们利用循环比较两条序列的每个字符,分三种情况。
举个小例子:
在这里插入图片描述(S1={1,3,4,5,6,7,7,8}和S2={3,5,7,4,8,6,7,8,2})

假如S1的最后一个元素 与 S2的最后一个元素相等,那么S1和S2的LCS就等于 {S1减去最后一个元素} 与 {S2减去最后一个元素} 的 LCS 再加上 S1和S2相等的最后一个元素。

假如S1的最后一个元素 与 S2的最后一个元素不等(本例子就是属于这种情况),那么S1和S2的LCS就等于 : {S1减去最后一个元素} 与 S2 的LCS, {S2减去最后一个元素} 与 S1 的LCS 中的最大的那个序列。

数学公式如下:
在这里插入图片描述

伪代码:

①设数组c[][] 和数组b[][],c[][] 记录此时最长公共子序列的长度,b[][] 记录产生最长公共子序列的过程。
②利用循环遍历比较每个字符,当字符相同时,此时最长公共子序列加一,记录过程为1;当c [i-1] [j] >= c [i] [j-1] 时,c [i] [j] = c [i-1] [j] ,记录过程为2;当c [i-1] [j] < c [i] [j-1] 时,相反,记录为3。
③通过b [i] [j] 倒推出S1和S2的LCS,并记录下标。
④打印输出,结束。
在这里插入图片描述

代码:

#include <iostream>
#include <string>

using namespace std;
void LCS(string s1,string s2)
{
   
    int m=s1.length()+1;
    int n=s2.length()+1;
    int **c;
    int **b;
    c=new int* [m];
    b=new int* [m];
    for(int i=0;i<m;i++)
    {
   
        c
  • 1
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值