关于动态规划中的最长子序列问题有很多优秀的解读,在这里推荐一位博主的关于最长子序列的文章,非常不错,配有大量的图片和文字解答,在这里推荐给大家。本文章转载自这里

1.基本概念

首先需要科普一下,最长公共子序列(longest common sequence)和最长公共子串(longest common substring)不是一回事儿。什么是子序列呢?即一个给定的序列的子序列,就是将给定序列中零个或多个元素去掉之后得到的结果。什么是子串呢?给定串中任意个连续的字符组成的子序列称为该串的子串。给一个图再解释一下:

如上图,给定的字符序列: {a,b,c,d,e,f,g,h},它的子序列示例: {a,c,e,f} 即元素b,d,g,h被去掉后,保持原有的元素序列所得到的结果就是子序列。同理,{a,h},{c,d,e}等都是它的子序列。

它的字串示例:{c,d,e,f} 即连续元素c,d,e,f组成的串是给定序列的字串。同理,{a,b,c,d},{g,h}等都是它的字串。

这个问题说明白后,最长公共子序列(以下都简称LCS)就很好理解了。
给定序列s1={1,3,4,5,6,7,7,8},s2={3,5,7,4,8,6,7,8,2},s1和s2的相同子序列,且该子序列的长度最长,即是LCS。

s1和s2的其中一个最长公共子序列是 {3,4,6,7,8}

2.特征分析

   解决LCS问题,需要把原问题分解成若干个子问题,所以需要刻画LCS的特征。

    以例子(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 中的最大的那个序列。这就是所谓的用动态规划解决最长子序列的状态转移方程的由来,很多文章并没有解释,使得很多同学不清不楚。我们假设dp[i][j]表示序列a中从0到i,以及序列b中从0到j这两段序列的最长子序列。于是根据上面分析:if(a[i]==b[j]){dp[i][j] = dp[i-1][j-1]+1;}elsedp[i][j] = max(dp[i][j-1],dp[i-1][j]);

计算LCS的长度

还是以s1={1,3,4,5,6,7,7,8},s2={3,5,7,4,8,6,7,8,2}为例。

结果

至此,该表填完。根据性质,c[8,9] = S1 和 S2 的 LCS的长度,即为5。

输出最长子序列内容

上面我们只是得到了最长子序列的长度,如果要得到具体的内容,我们可以逆推回去。

我们根据递归公式构建了上表,我们将从最后一个元素c[8][9]倒推出S1和S2的LCS。
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] 这种存在分支的情况,这里请都选择一个方向(之后遇到这样的情况,也选择相同的方向)。

第一种结果为:

这就是倒推回去的路径,棕色方格为相等元素,即LCS = {3,4,6,7,8},这是其中一个结果。

即LCS ={3,5,7,7,8}。

动态规划:最长子序列问题相关推荐

  1. 动态规划----最长子序列

    引出: 问题描述:给出一个序列a1,a2,a3,a4,a5,a6,a7-.an,求它的一个子序列(设为s1,s2,-sn),使得这个子序列满足这样的性质,s1<s2<s3<-< ...

  2. 动态规划之-----单调递增最长子序列(nyoj17)

    单调递增最长子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 求一个字符串的最长递增子序列的长度 如:dabdbf最长递增子序列就是abdf,长度为4 输入 第一行 ...

  3. 【算法】【递归与动态规划模块】两个字符串的公共最长子序列

    目录 前言 问题介绍 解决方案 代码编写 java语言版本 c语言版本 c++语言版本 思考感悟 写在最后 前言 当前所有算法都使用测试用例运行过,但是不保证100%的测试用例,如果存在问题务必联系批 ...

  4. 单调递增最长子序列(动态规划)

    7-1 单调递增最长子序列 (20分) 设计一个 O(n2)时间的算法,找出由n个数组成的序列的最长单调递增子序列. 输入格式: 输入有两行: 第一行:n,代表要输入的数列的个数 第二行:n个数,数字 ...

  5. LeetCode 1615. 最大网络秩 / 2389. 和有限的最长子序列 / 1626. 无矛盾的最佳球队(排序+动态规划)

    1615. 最大网络秩 2023.3.15 每日一题 题目描述 n 座城市和一些连接这些城市的道路 roads 共同组成一个基础设施网络.每个 roads[i] = [ai, bi] 都表示在城市 a ...

  6. 动态规划求一个序列的最长回文子序列(Longest Palindromic Substring )

    1.问题描述 给定一个字符串(序列),求该序列的最长的回文子序列. 2.分析 需要理解的几个概念: ---回文 ---子序列 ---子串 http://www.cnblogs.com/LCCRNblo ...

  7. 最长子序列DP和二分法

    输入一串数字例如: 5 6 8 1 3 4 9 输出最长递增子序列长度,示例中即 1 3 4 9或5 6 8 9 ,最大长度为4 public static void main(String[] ar ...

  8. 最长递增子序列问题 nyoj 17单调递增最长子序列 nyoj 79拦截导弹

    一,    最长递增子序列问题的描述 设L=<a1,a2,-,an>是n个不同的实数的序列,L的递增子序列是这样一个子序列Lin=<aK1,ak2,-,akm>,其中k1< ...

  9. 单调递增最长子序列 - 从最长公共子序列到单调递增最长子序列

    最长公共子序列 的 算法思路 在这里 点击进入  将 代码稍微改动一下 就可以   ,   最长公共子序列  是两个 字符串求 公共子序列  , 可以将其中的 一个 改为 从 a 到 z  这样输入另 ...

最新文章

  1. python编程有哪些-python编程工具有哪些
  2. 输入和学生成绩的输出
  3. My first App EncryptWheel is in WAITING FOR REVIEW status
  4. RecyclerView
  5. 互联网企业安全高级指南3.6 需要自己发明安全机制吗
  6. [转载] Java获取泛型T的类型 T.class
  7. 大数据时代:数据质量逐渐成关注焦点
  8. 深度数据对接 链接服务器 数据传输
  9. 解决PHP不打印任何东西浏览器输出字符串
  10. JAVA程序设计教程-第2版-雍俊海 介绍以及 PDF+源代码+ppt 下载链接
  11. java中mysql的优化,Java培训实战教程之mysql优化
  12. 传输速率和传播速率的理解
  13. 计算机怎么看显卡内存容量,Win10系统显卡显存大小怎样查看?Win10查看显存大小的两种方法...
  14. shutdown immediate 太慢,需要进行进程查杀
  15. (FAQ)VM log是做什么的,4 Way VM又是什么
  16. 汉字数组,配合转换拼音
  17. 鲲鹏服务器cpu性能,华为发布鲲鹏920处理器:业界性能最强
  18. python实现“幻影坦克”效果(点开图片是隐藏的另一张图)【详解】
  19. 金融信贷业务-贷前整理
  20. python抓取淘宝关键字信息

热门文章

  1. 【Python网络爬虫】基本原理
  2. 设计UI的语言——XAML
  3. 自定义时间(小时:分钟)选择器
  4. 纯粹CSS 绘制向下箭头
  5. ps制作台式计算机图标,图标制作,用PS制作计算机应用的图标
  6. 利用快慢指针判断循环
  7. storm DRPC例子
  8. 数学建模:线性规划及 Python 求解
  9. [C]sprintf用法
  10. 关于我AbortME