LCIS 最长上升公共子序列
来源:互联网 发布:mysql 命令行导入 编辑:程序博客网 时间:2024/05/16 07:20
LCIS 最长上升公共子序列
前言
LCIS 指的是一个两个序列中最长的公共子序列,且这个子序列需要满足单调递增的这个性质。但是目前据我所知并不存在 LCIS 的 nlogn 算法,因此在这里将介绍 LCIS 的 n ^ 2 算法
算法分析
首先我们需要确定出 f 数组的定义,在这里我定义 f[i][j] 表示的是 a 数组的前 i 个数, b 数组前 j 个数并以 b[j] 结尾的最长上升公共子序列的长度
明确出 f 数组的定义之后,类比 LCS 的 n ^ 2 做法的状态转移方程,就可以推出状态转移方程了:
当 a[i] != b[j] 时: f[i][j] = f[i - 1][j]
当 a[i] == b[j] 时:f[i][j] = max(f[i - p][k]) + 1 (p ≤ k ≤ j - 1 且 b[j] > b[k])
这个状态转移方程的正确性是显而易见的,但是如果朴素实现这个状态转移方程的时间复杂度是 O(n ^ 3)。而实现我们所期待的 O(n ^ 2),则需要按照一个合理的递推顺序。
外层循环枚举 i ,内层循环枚举 j 。a[i] == b[j] 的情况中有一个条件是 b[j] > b[k],由于 b[j] == a[i],这个条件可以改写成 a[i] > b[k]。内层循环 j 是由小至大枚举的,因此我们可以在枚举 j 的同时计算出对应的 k 。当 k 固定时, f[m][k] 是一个单调不递减的序列,那么 i - p 便无需枚举,因为 i - p 取最大值的时候 f[i - p][k] 一定取最大值
综上所述,我们可以在内层循环中维护一个 MAX 值,这个 MAX 的值是 f[i - 1][k] 的最大值且满足 a[i] > b[k] 。维护的方法非常简单,当 a[i] > b[j] 时令 MAX = max(MAX, f[i - 1][j]) 即可。由于我们维护了这个 MAX,当遇到 b[j] == a[i] 的情况时直接赋值为 MAX + 1即可。
答案为 max(f[len_a][i]) (1 ≤ i ≤ len_b)
代码
for (int i = 1; i <= a_len; i++) { int MAX = 0; for (int j = 1; j <= b_len; j++) { if (a[i] > b[j]) MAX = max(MAX, f[i - 1][j]); if (a[i] == b[j]) f[i][j] = MAX + 1; else f[i][j] = f[i - 1][j]; }}
空间压缩
我们可以发现当 a[i] != b[j] 时,f[x][j] = f[x - 1][j],这说明此时我们无需改变,沿用上层数据即可,仅当 a[i] == b[j] 时令 f[j] = MAX + 1 即可。可以发现这个算法并没有优化任何的时间复杂度,仍然是 O(n ^ 2)
代码
for (int i = 1; i <= a_len; i++) { int MAX = 0; for (int j = 1; j <= b_len; j++) { if (a[i] > b[j]) MAX = max(MAX, f[j]); if (a[i] == b[j]) f[j] = MAX + 1; }}
- 最长公共上升子序列(LCIS)
- [DP]最长公共上升子序列LCIS
- 最长公共上升子序列 LCIS
- 最长公共上升子序列LCIS
- 最长公共上升子序列 LCIS
- 最长上升公共子序列(LCIS)
- Codevs_P2185 最长公共上升子序列(LCIS)
- P1071 LCIS 最长公共上升子序列
- 最长公共上升子序列LCIS
- 最长公共上升子序列LCIS
- LCIS 最长上升公共子序列
- 最长公共上升子序列 LCIS
- 杭电 1423 (最长上升公共子序列 LCIS )
- 最长公共上升子序列 LCIS O(NM) 方案
- hdu 1423 最长上升公共子序列 LCIS 模板题
- LCIS最长上升公共子序列(HDU 1423)
- (LCIS)最长公共上升子序列 ZOJ 2432
- 最长公共上升子序列(LCIS)ZOJ 2432
- <DP版>codevs 3304 水果姐逛水果街Ⅰ
- SQL中的事务
- Error using == vertcat CAT arguments dimensions are not consistent.
- Implement Queue using Stacks
- spring boot启动器
- LCIS 最长上升公共子序列
- 使用AVPlayer遇到的那些坑
- 归并排序python
- Github进行fork后如何与原仓库同步
- Git--远程仓库的使用和多仓库管理
- 项目中的小Tip
- 单点登录原理与简单实现
- 关于如何讲字符串中的空格或者\n替换为\r\n
- 数据库——sql主机