• LCS最长公共子序列的延伸情况(可连续的子序列)


         看过《算法导论》的人应该知道,动态规划中一个非常经典的例子就是LCS(Longest Common Length)最长公共子序列问题。下面我们来回顾一下LCS的概念。

        假设有两个字符串,X=<A, B, C, B, D, A, B>,Y=<B, D, C, A, B, A>,那么它们的最长公共子序列为<B, C, B, A>,它的特点在于每个字符可以不连续。LCS问题在实际中也有非常多的应用,比如说用于论文查重等。

        都说表达一个动态规划算法的精髓在于状态转移方程,那么我们就顺便回忆一下LCS的状态转移方程吧。如果用c[i, j]来表示序列Xi和Yi的LCS的长度,那么有状态转移方程:

        下面进入本文的重点。如果将LCS的条件加严,要求子序列中的字符必须是连续的。那么应该如何求解这个最长公共连续子序列呢?

        为了便于书写,后文中再提到“最长公共连续子序列”,我都一律用STRICT-LCS代替。

        为了便于理解,还是用之前的两个字符串来举例说明什么是STRICT-LCS。X=<A, B, C, B, D, A, B>,Y=<B, D, C, A, B, A>。那么它们的最长公共连续子序列为<B, D>。

        我们仍然用Dynamic Programming求解。只不过在原来的基础上需要改变。首先,我们定义c[i, j]跟原来的意义略有不同。这里c[i, j]指的是最后一个元素为Xi(=Yj)的STRICT-LCS的长度,比如X=<A, B, C>,Y=<A, B, D>那么c[3, 3]=0,不管前面如何,如果Xi和Yj不相等,就得将c[i, j]清零,作为新的开始。

        LCS中,c[i, j]的值随着i、j值增大而渐渐增大,有累计效应;但是STRICT-LCS中,c[i, j]的值随时可能在某个时刻被清零。

        说了这么多,把状态转移方程写出来吧:

        伪代码的话,也比较简单。

     1 STRICT-LCS-LENGTH(X, Y)
     2 m = length[X]
     3 m = length[Y]
     4 for i = 1 to m
     5     do c[i, 0] = 0
     6 for j = 0 to n
     7     do c[0, j] = 0
     8 for i = 1 to m
     9     do for j = 1 to n
    10         do if Xi=Yj
    11             then c[i, j] = c[i-1, j-1]+1
    12             else c[i, j] = 0
    13 return c

      

        下面做一个显示推导过程的图。 

       

        从上图中可以找到值最大的格子2,故可知X和Y的最长公共连续子序列为BD,和AB,两个子序列的长度都为2.

    e

  • 相关阅读:
    日志统计|2018年蓝桥杯B组题解析第八题-fishers
    螺旋折线|2018年蓝桥杯B组题解析第七题-fishers
    递增三元组|2018年蓝桥杯B组题解析第六题-fishers
    乘积尾零|2018年蓝桥杯B组题解析第三题-fishers
    明码|2018年蓝桥杯B组题解析第二题-fishers
    第几天|2018年蓝桥杯B组题解析第一题-fishers
    2016年蓝桥杯B组C/C++省赛(预选赛)题目解析
    2016年蓝桥杯B组C/C++省赛(预选赛)试题
    计蒜客习题:同余方程
    数论——同余方程
  • 原文地址:https://www.cnblogs.com/ErinCodeMM/p/2747042.html
Copyright © 2020-2023  润新知