• 最长连续公共子序列(LCS)与最长递增公共子序列(LIS)


    最长公共子序列(不连续)

    实际问题中也有比较多的应用,比如,论文查重这种,就是很实际的一个使用方面。

    这个应该是最常见的一种了,不再赘述,直接按照转移方程来进行:

    clip_image001

    按最普通的方式就是,直接构造二维矩阵,两个序列分别是Ai 以及 Bj ,c[i,j]就表示的是第一个序列的从开始到第Ai个元素,以及第二个序列的从开始到第Bj个元素,这两部分序列的最长的公共子序列,如果ai==bj,则斜对角加1,否则就是前面和上面的元素中最大的那一个,就是按照这种方式,一层层的向下递推。

    最长连续公共子序列

    就是strict-LCS的情形,

    这里c[I,j]的定义与原来有所不同,这里的才c[I,j]指的是最后一个元素为xi时候,并且xi==yj时候的的长度。

    不论前面的情况如何,如果xi与yj不相等,就将c[I,j]归为0 其实转移方程也还是比较简易的:

    clip_image002

    就是把累加性的部分去掉就好了。

    PAT1040

    这个最终也可以转化成LCS的思路来求解 如果一个序列中间有连续的对称部分的话 不过这个是最长连续的公共子序列。

    最长递增公共子序列

    1045

    这个是比较典型的

    这个可以有多种解法

    一个是转化成LCS,一个是就用最本来的LIS的递归的方法,可以参考这个:

    http://blog.csdn.net/joylnwang/article/details/6766317

    其实转化成LCS,可以算成一种变形:

    http://blog.csdn.net/tiantangrenjian/article/details/19921051

    这个可以算成是公共部分可以重复的最长公共子序列,但是这个重复的部分也应该是其中某个序列中的,整体来说,就是这个题目的背景。

    这个时候递归的时候:
    还是通过矩阵向后递推,只是:

    先要求出max元素,如果当前的元素是c[I,j],那么c[i-1][j] c[I,j-1] c[i-1,j-1]中的最大一个,把它称为max元素,通常像这样:

    1.  max = len[i-1][j-1]; 

    2. if(max < len[i][j-1])max = len[i][j-1]; 

    3. if(max < len[i-1][j])max = len[i-1][j];      //先求出左边、上边、左上边 三个值中的最大值

    A[i]=B[j]的时候 直接才c[I,j]=max+1

    A[i]!=B[j]的时候 直接c[I,j]=max

    注意这里直接放成max 根据max往后走。

    对于这个题,还是用这种方法比较好,要是用最简单的LCS就是按照color出现的顺序来对原来的stripe进行排序,并且将没有出现的元素滤去,这样需要申请m[N][N]的空间,题中的N给的比较大,很可能超时。

    LCS的递归不像背包问题的那种,可以用一行来结局,要是用两行的话,就得不断的把之前的一行保存下来,这里N的时候,又是容易发生超时。

  • 相关阅读:
    【SSH网上商城项目实战11】查询和删除商品功能的实现
    【SSH网上商城项目实战10】商品类基本模块的搭建
    【SSH网上商城项目实战09】添加和更新商品类别功能的实现
    【SSH网上商城项目实战08】查询和删除商品类别功能的实现
    【SSH网上商城项目实战07】Struts2和Json的整合
    【SSH网上商城项目实战06】基于DataGrid的数据显示
    thinkphp模版主题使用方法
    sql语句中#{}和${}的区别
    SQL语句中有关单引号、双引号和加号的问题
    LEFT JOIN 关键字语法
  • 原文地址:https://www.cnblogs.com/Goden/p/4152537.html
Copyright © 2020-2023  润新知