最长公共子序列(LCS)是经典的DP问题,求序列a[1...n], b[1..m]的LCS。

状态是DP[i][j],表示a[1..i],b[1..j]的LCS。

DP转移方程是

DP[i][j]=

  DP[i-1][j-1]+1,  a[i] == b[j]

  max{ DP[i][j-1], DP[i-1][j] },  a[i] != b[i] 

-------------------------------------------------------------------------------------------

时间复杂度O(N^2),空间复杂度0(N^2)。

使用滚动数组,可将空间复杂度降到 0(N)。

观察DP转移方程可看出,即使用滚动数组,也需要两个即DP[2][N],一个DP[N]行不通。

因为若只用一维数组DP[N]来保存状态,第一个式子要求从右向左更新,第二个式子要求从左向右更新。

------------------------------------------------------------------------------------

以上关于用滚动数组降低空间复杂度的论述有误

----------------------------------------------------------------

实际上只用一维数组DP[N]也可以。严格地说,上面的论述并没有错,若严格按照

DP[i][j]=

  DP[i-1][j-1]+1,  a[i] == b[j]

  max{ DP[i][j-1], DP[i-1][j] },  a[i] != b[i] 

来转移,一个DP[N]确实不够,但我们深入分析下一开始的论据--"第一个式子要求从右向左更新",

如果第一式也从左向右更新,那么在需要DP[i-1][j-1]时,它已被DP[i][j-1]覆盖

自然地,我们考虑把DP[i-1][j-1]单独存起来,问题就解决了。

---------------------------------------------------------------------------------------------------------------------------------------

还有一种思路,我们略微变通一下,将第一个转移方程改为

DP[i][j] = max{ DP[i-1][k] : k < j } +1

这样只要在从左到右更新时维护一个max{ DP[i-1][k] : k < j }

而DP[i-1][k] >= DP[i-1][k-1] (k >=1),所以实际上只要在计算DP[i][j]之前,把DP[i-1][j]存起来以备查询。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

伪代码

FOR i := 0 to n

  dp[i] := 0

END FOR

FOR i := 1 to n

  tmp := dp[0]

  FOR j := 1 to m

    IF a[i] = b[j]

      IF tmp = dp[j]

        dp[j] := tmp + 1

      ELSE

        tmp := dp[j]

      END IF

    ELSE

      tmp := dp[j]

      dp[j] := max{dp[j], dp[j-1]}

    END IF

  END FOR

END FOR

      

Longest Common Subsequence (LCS)的更多相关文章

  1. 动态规划求最长公共子序列(Longest Common Subsequence, LCS)

    1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...

  2. 最长公共字串算法, 文本比较算法, longest common subsequence(LCS) algorithm

    ''' merge two configure files, basic file is aFile insert the added content of bFile compare to aFil ...

  3. 动态规划 ---- 最长公共子序列(Longest Common Subsequence, LCS)

    分析: 完整代码: // 最长公共子序列 #include <stdio.h> #include <algorithm> using namespace std; ; char ...

  4. LintCode Longest Common Subsequence

    原题链接在这里:http://www.lintcode.com/en/problem/longest-common-subsequence/ 题目: Given two strings, find t ...

  5. Longest Common Subsequence

    Given two strings, find the longest common subsequence (LCS). Your code should return the length of  ...

  6. Longest Common Subsequence & Substring & prefix

    Given two strings, find the longest common subsequence (LCS). Your code should return the length of  ...

  7. Lintcode:Longest Common Subsequence 解题报告

    Longest Common Subsequence 原题链接:http://lintcode.com/zh-cn/problem/longest-common-subsequence/ Given ...

  8. [Algorithms] Longest Common Subsequence

    The Longest Common Subsequence (LCS) problem is as follows: Given two sequences s and t, find the le ...

  9. 【Lintcode】077.Longest Common Subsequence

    题目: Given two strings, find the longest common subsequence (LCS). Your code should return the length ...

随机推荐

  1. Linq中查询List组合相同值数量大于1

     List< select g.Key).ToList();

  2. css3d

    立方体:http://sandbox.runjs.cn/show/1h6zvghj 原理分析:(左负右正) x:与屏幕水平:(在屏幕上) y:与屏幕水平方向垂直(在屏幕上) z:垂直于屏幕(在屏幕外) ...

  3. 理解SQL Server中的权限体系(上)----主体

    原文:http://www.cnblogs.com/CareySon/archive/2012/04/10/mssql-security-principal.html 简介 权限两个字,一个权力,一个 ...

  4. 区块链技术(一):Truffle开发入门

    以太坊是区块链开发领域最好的编程平台,而truffle是以太坊(Ethereum)最受欢迎的一个开发框架,这是我们第一篇区块链技术文章介绍truffle的原因,实战是最重要的事情,这篇文章不讲原理,只 ...

  5. js 中常用的方法

    1..call() 将.call()点之前的属性或方法,继承给括号中的对象. 2.(function(){xxx})() 解释:包围函数(function(){})的第一对括号向脚本返回未命名的函数, ...

  6. ASP.net MVC自定义错误处理页面的方法

    在ASP.NET MVC中,我们可以使用HandleErrorAttribute特性来具体指定如何处理Action抛出的异常.只要某个Action设置了HandleErrorAttribute特性,那 ...

  7. python 控制 cmd 命令行颜色

    基于win7 + python3.4 import ctypes import sys '''Windows CMD命令行颜色''' # 句柄号 STD_INPUT_HANDLE = -10 STD_ ...

  8. html 元素 绝对位置坐标

    $(".seriesListings-itemContainer").click(function(){$(this).css("border","1 ...

  9. error C2065: “CMainFrame”: 未声明的标识符

    xxxView.cp的开头包含 框架的头文件即可 : #include "MainFrm.h"

  10. 《android基于andFix的热修复方案》思路篇

    1:需求背景 项目上线之后,发现BUG需要修复(比如安卓兼容性等测试难以发现的问题),频繁的更新影响用户体验 2:方案要求 静默下载,耗费流量少,打完补丁后立刻生效,不用重启apk 3:解决思路 3. ...