最长公共子序列(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. Hill密码

    希尔密码(Hill Password)是运用基本矩阵论原理的替换密码,由Lester S. Hill在1929年发明.每个字母当作26进制数字:A=, B=, C=... 一串字母当成n维向量,跟一个 ...

  2. VideoView 播放资源目录raw下的视频

    你把影片copy到res/raw下!檔名小寫加底線,例如:default_video.3gp,在程式碼裡指定uri路徑 String uri = "android.resource://&q ...

  3. 使用clone( )和Cloneable接口

    由Object类定义的绝大部分方法在本书其他部分讨论.而一个特别值得关注的方法是clone( ).clone( )方法创建调用它的对象的一个复制副本.只有那些实现Cloneable接口的类能被复制. ...

  4. Saltstack-自动化部署

    Saltstack概述 Salt一种全新的基础设施管理方式,部署轻松,在几分钟内可运行起来,扩展性好,很容易管理上万台服务器,速度够快,服务器之间秒级通讯. salt底层采用动态的连接总线, 使其可以 ...

  5. python-基础案例

    范例一: 练习:元素分类 有如下值集合 [11,22,33,44,55,66,77,88,99,90...],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值 ...

  6. S2--《深入.NET平台和C#编程》

    第一章    深入.NET框架 1.1  Microsoft  .NET框架概述 .NET框架的优势 * 提供了一个面向对象的编程环境,完全支持面向对象编程,.NET 框架提高了软件的可复用性,可扩展 ...

  7. 14SpringMvc_在业务控制方法中写入HttpServletRequest,HttpServletResponse等传统web参数(这个知识点知道就好了,不推荐这么去做)

    这篇文章解决的问题是怎么在业务方法里面引入我们熟悉的HttpServletRequest和HttpServletRespon? 答案:这种引入传统的web参数的做法不推荐去做,因为这么做会实行高度耦合 ...

  8. R 分类进行数值处理

    主要Mark一下R程序中,分类进行数值计算的情况. 1.aggregate函数 有数据框case,列名分别a,b,c,d,e,f (1)根据一列对另一列求和:根据a,对d求和 sum1 <- a ...

  9. 如何配置CentOS或者RedHat5.X、6.X、7.X的网络yum源

    第一步:找到一个可靠的yum源 中科大帮助:https://lug.ustc.edu.cn/wiki/mirrors/help/centos源:http://mirrors.ustc.edu.cn/c ...

  10. An Introduction to Interactive Programming in Python (Part 1) -- Week 2_1 练习

    # Practice Exercises for Functions # Solve each of the practice exercises below. # 1.Write a Python ...