• Longest Increasing Common Subsequence (LICS)


    最长上升公共子序列(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)的复杂度还是偏高的,不知这是否理论复杂度。

  • 相关阅读:
    Spring 中使用 Hibernate
    数据源
    Spring 对 DAO 的支持
    Spring Boot 整合模板引擎 Freemaker、thymeleaf
    Spring Boot 使用 Filter、Servlet、Listener、Interceptor
    Spring Boot 全局异常
    Spring Boot 启动方式
    Spring MVC 异常处理
    Spring MVC 装配拦截器
    结构体做函数参数
  • 原文地址:https://www.cnblogs.com/Patt/p/4743811.html
Copyright © 2020-2023  润新知