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)的复杂度还是偏高的,不知这是否理论复杂度。
- POJ - 1679 The Unique MST(次小生成树)
- NSString/NSMutableString/NSNumber/NSValue
- hdu 5400 Arithmetic Sequence
- hdu 2817 A sequence of numbers(快速幂)
- 动态改变UITabBarController的菜单文字
- easyui------显示隐藏列功能
- UIView.animateWithDuration 没有动画过渡效果直接跳到最后
- UIScrollView滚动时隐藏底部导航栏问题
- LightOJ 题目1427 - Substring Frequency (II)(AC自动机)
- 实现UITableView循环利用
- STL使用:deque双端队列
- 8.18 [LeetCode 52] N-Queens II
- UI_04 事件处理
- uva 11248 Frequency Hopping (最大流)
- HDU 3836--Equivalent Sets【求有向图最少增加多少边使图强连通 && Scc缩点新建图】
- priority_queue优先队列容器
- UVA 694-The Collatz Sequence
- GUID全球唯一标识
- GUID全球唯一标识
- ios UIButton的图片和文字位置