zoukankan      html  css  js  c++  java
  • 最长连续公共子序列(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的时候,又是容易发生超时。

  • 相关阅读:
    156. Binary Tree Upside Down
    155. Min Stack
    154. Find Minimum in Rotated Sorted Array II
    153. Find Minimum in Rotated Sorted Array
    汉诺塔问题
    算法——二分搜索
    linux内核编程helloworld(中级)
    linux内核入门(1)——基本简介和编译
    linux网络编程概念(一)
    linux配置防火墙
  • 原文地址:https://www.cnblogs.com/Goden/p/4152537.html
Copyright © 2011-2022 走看看