最长上升公共子序列(Longest Increasing Common Subsequence,LICS)也是经典DP问题,是LCS与LIS的混合。

Problem

求数列 a[1..n], b[1..m]的LICS的长度, a[], b[]数组的元素均为正整数。

Solution

考虑如何定义DP状态,定义DP状态就是定义所谓的最优子问题(optimal subproblem),而DP状态要能转移,就是所谓最优子问题要具有重叠子结构

将DP状态定义为

DP[i][j]:a[1..i], b[1..j]的以b[j]结尾的LICS的长度

状态转移方程为

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

= max{DP[i][k] : k<j, b[k] < b[j]} + 1,  a[i] == b[j]

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

上面的转移方程,时间复杂度为O(N^3), 空间复杂度为O(N^2),都不能接受,必须优化。

先考虑时间优化,不难发现无法O(1)转移的是a[i]==b[j]的情况,我们考虑在转移的同时维护的这种情况所需要的那个最大值。

我们将转移过程写成两循环

  for(i=1; i<=n; i++)

    for(j=1; j<=m; j++)

      dp[i][j]..

i在外层循环,内层循环时i不变。

我们将第二种情况下的转移方程该成 DP[i][j] = max{DP[i][k] : k<j, b[k]<a[i]} + 1, a[i] == b[j]

优化的方法就显而易见了,在每层内循环内维护 max{ DP[i][k] : k<j, b[k]<a[i] }

  for(i=1; i<=n; i++)

    for(j=1, ma=0; j<=m; j++)

      if(b[j]==a[i])

        dp[i][j]=ma+1;

      else{

        dp[i][j]=dp[i-1][j];

        if(a[i]>b[j])

          ma=max(ma, dp[i][j]);

      }

这样时间上就优化到O(N^2)

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

再考虑空间优化,根据转移方程不难看出可用滚动数组

    for(i=1; i<=n; i++)

      for(j=1, ma=0; j<=m; j++)

        if(a[i]==b[j])

          dp[j]=ma+1;

        else if(a[i]>b[j])

          ma=max(dp[j], ma);

空间优化到O(N)

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

不难看出DP的一切优化都建立在正确的转移方程之上,所以对于DP问题,写转移方程是最关键的一步。

LICS的O(N^2)的复杂度还是偏高的,不知这是否理论复杂度。

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

  1. [LintCode] Longest Increasing Continuous Subsequence 最长连续递增子序列

    Give an integer array,find the longest increasing continuous subsequence in this array. An increasin ...

  2. [LintCode] Longest Increasing Continuous subsequence

    http://www.lintcode.com/en/problem/longest-increasing-continuous-subsequence/# Give you an integer a ...

  3. LintCode 397: Longest Increasing Continuous Subsequence

    LintCode 397: Longest Increasing Continuous Subsequence 题目描述 给定一个整数数组(下标从0到n - 1,n表示整个数组的规模),请找出该数组中 ...

  4. Lintcode397 Longest Increasing Continuous Subsequence solution 题解

    [题目描述] Give an integer array,find the longest increasing continuous subsequence in this array. An in ...

  5. LintCode "Longest Increasing Continuous subsequence II" !!

    DFS + Memorized Search (DP) class Solution { int dfs(int i, int j, int row, int col, vector<vecto ...

  6. 300. Longest Increasing Subsequence

    题目: Given an unsorted array of integers, find the length of longest increasing subsequence. For exam ...

  7. 300最长上升子序列 · Longest Increasing Subsequence

    [抄题]: 往上走台阶 最长上升子序列问题是在一个无序的给定序列中找到一个尽可能长的由低到高排列的子序列,这种子序列不一定是连续的或者唯一的. 样例 给出 [5,4,1,2,3],LIS 是 [1,2 ...

  8. <Sicily> Longest Common Subsequence

    一.题目描述 Given a sequence A = < a1, a2, -, am >, let sequence B = < b1, b2, -, bk > be a s ...

  9. Longest common subsequence(LCS)

    问题 说明该问题在生物学中的实际意义 Biological applications often need to compare the DNA of two (or more) different ...

随机推荐

  1. ArcGis实现添加MultiLayerMarkerSymbol(多个符号叠加生成新的符号)

    , , );             pMarkerSymbol.Angle = ;             pMarkerSymbol.XOffset = ;;;;, , );            ...

  2. Saltstack-进阶篇

    查看minion端的文件内容 [root@linux-node2 ~]# cat /etc/resolv.conf # Generated by NetworkManager nameserver 1 ...

  3. 使用CSS3制作72个webapp图标

    前言 移动网络带宽的快慢直接影响webapp应用体验效果的优差,其中加载图片是很耗流量的,所以对这一方面的性能优化是很需要的.一般对于那些小而多的图片(图标)都会采用sprite合并成一张图片来减少h ...

  4. Socket Programming in C#--Multiple Sockets

    Now lets say you have two sockets connecting to either two different servers or same server (which i ...

  5. Linux 进程与线程三(线程比较--创建线程参数)

    int pthread_equal(pthread_t th1,pthread_t th2); pthread_equal函数比较th1与th2是否为同一线程,由于不可以讲pthread_t数据类型认 ...

  6. Linux 信号概念

    程序在执行的时候,几乎任何时刻都会反生事件. 信号通常用来向一个进程通知事件. 信号是不可提前预知的,所以信号是异步的. 信号随时都可能发生,接收信号的进程也可以没有控制权. 每个信号名都以SIG开头 ...

  7. C#中成员初始化顺序

    http://blog.csdn.net/huangcailian/article/details/25958967 一.成员初始化整体顺序 1.成员赋值初始化先于构造函数: 2.成员赋值初始先从子类 ...

  8. Backbone源码分析-Backbone架构+流程图

    作者:nuysoft/高云/nuysoft@gmail.com 声明:本文为原创文章,如需转载,请注明来源并保留原文链接. Backbone0.9.1源码分析分析系列 jQuery1.6.1源码分析系 ...

  9. 反射中getMethods 与 getDeclaredMethods 的区别

    public Method[] getMethods()返回某个类的所有公用(public)方法包括其继承类的公用方法,当然也包括它所实现接口的方法.public Method[] getDeclar ...

  10. linux实践——ELF分析

    一.ELF的部分结构定义 elf header(定义在/usr/include/elf.h)//64位的系统ELF文件头包括以下两个部分 #define EI_NIDENT (16) typedef ...