最长公共上升子序列LCIS,如字面意思,就是在对于两个数列A和B的最长的单调递增的公共子序列。

这道题目是LCS和LIS的综合。

在LIS中,我们通过两重循环枚举当序列以当前位置为结尾时,A序列中当前位置之前的数是否比当前位置的数大为条件,进行对于“最长上升子序列”的长度的转移。

方程简单的表示为:f[i] = max{f[i], f[j +1]}(0 <= j < i)

边界为f[0] = 0, 目标为max{f[i]}(1 <= I <= N)

在LCS中,我们使用二维数组,对于状态“f[i, j]表示前缀子串a[1 ~ i]和b[1 ~ j]的最长公共子序列的长度”,将阶段划分为已经处理的前缀长度,f[Ii, j]的长度转移为f[i - 1][j]和f[i][j - 1]的长度,即i的上一位置得到的最长公共子序列长度与当前位置j的前一个位置的最长公共子序列长度,当a[i] == b[j]是,我们还要比较f[i][j]与f[i - 1][j - 1] +1的长度,即a序列与b序列在前一位置的最长公共子序列长度向后扩展1的总长度与当前位置所能够得到的最长公共子序列的长度进行比较,更新最长公共子序列长度

对于LCIS,最长公共上升子序列,我们首先要解决的是公共,然后在解决上升,综合LIS和LCS解法,我们容易得到一个三重循环的写法。

F[I, j]表示A1~Ai与B1~Bj可以构成以Bj为结尾的LCIS的长度。

假设A0 = B0= -∞。

当Ai != Bj时,有f[i, j] = f[i – 1, j]

当Ai == Bj时,有

F[i, j] = max{f[i – 1, k]} + 1(0 <= k < j, Bk < Bj) = max(f[i – 1, k]) + 1(0 <= k <j, Bk < Ai)

这样我们很容易就能把代码写出来

for(int i = ; i <= n; ++i)
for(int j = ; j <= m; ++j) {
if(a[i] == b[j])
for(int k = ; k < j; ++k)
if(b[k] < a[i]) f[i][j] = max(f[i][j], f[i - ][k] + );
else f[i][j] = f[i - ][j];
}

但是三重循环显然不是一个优秀的解法,我们思考如何优化。

在转移过程中,我们把满足0 <= k < j并且Bk < Ai的k构成的集合称为f[i, j]进行状态转移时的决策集合,记为s[i, j],注意到当第二层循环j增加到m时,j是个定值, 这使得条件Bk小于Ai是固定的,也就是说对于决策集合s[i, j]中的k,Bk小于当前层的Ai是不会有变动的

因此,当变量j增加1是,k的范围变为0 <= k < j + 1,即整数j可能会进入新的决策集合,也就是说,我们只需要O(1)判断Bj < Ai是否满足即可,已经在决策集合中的数则一定不会被去除….(emmm好难懂,终于想通了),再详细的说就是,当j增加1时,对于k,实际取值变化只是右端多加了1,所以我在填充决策集合时,实际上只需要对刚刚增大的j值进行判断就行了,也就是直接判断Bj < Ai是否成立来判断能否加入决策集合

s(i, j +1) = <1> s(i, j) (Bj >= Ai)

<2> s(i, j) ∪ {j} (Bj < Ai)

所以上述状态转移方程只需要两重循环即可求解

 for(int i = ; i <= n; ++i) {
int val = ;//val是决策集合s(i, j)中f[i - 1][k]的最大值
if(b[] < a[i]) val = f[i - ][];//j = 1时,0可以作为b的取值
for(int j = ; j <= m; ++j) {
if(a[i] == b[j]) f[i][j] = val + ;
else f[i][j] = f[i - ][j];
if(b[j] < a[i]) val = max(val, f[i - ][j]);//j即将增大为j + 1,检查j能否进入决策集合
}
}

从这道题的优化中,我们可以总结到,在实现状态转移方程时,要注意观察决策集合的范围随着状态的变化情况,对于“决策集合中的元素只增多不减少”的情景,就可以像本体一样维护一个变量来记录决策集合的当前信息,避免重复扫描,把转移的复杂度降低一个量级

LCIS最长公共上升子序列的更多相关文章

  1. [CodeForces10D]LCIS(最长公共上升子序列) - DP

    Description 给定两个数列,求最长公共上升子序列,并输出其中一种方案. Input&Output Input 第一行一个整数n(0<n<=500),数列a的长度. 第二行 ...

  2. LCIS 最长公共上升子序列问题DP算法及优化

    一. 知识简介 学习 LCIS 的预备知识: 动态规划基本思想, LCS, LIS 经典问题:给出有 n 个元素的数组 a[] , m 个元素的数组 b[] ,求出它们的最长上升公共子序列的长度. 例 ...

  3. CF10D LCIS 最长公共上升子序列

    题目描述 This problem differs from one which was on the online contest. The sequence a1,a2,...,an a_{1}, ...

  4. LCIS(最长公共上升子序列)Vijos1264神秘的咒语

    描述 身为拜月教的高级间谍,你的任务总是逼迫你出生入死.比如这一次,拜月教主就派你跟踪赵灵儿一行,潜入试炼窟底. 据说试炼窟底藏着五行法术的最高法术:风神,雷神,雪妖,火神,山神的咒语.为了习得这些法 ...

  5. LCIS 最长公共上升子序列

    这个博客好久没写了,这几天为了准备清华交叉研究院的夏令营,在复习大一大二ACM训练时的一些基础算法,正好碰到LICS,发现没有写在博客里,那就顺便记录一下好了. 参考链接:http://blog.cs ...

  6. LCIS(最长公共上升子序列)模板

    求出LCIS并输出其路径. 1 #include <iostream> 2 #include <cstdio> 3 #include <string> 4 #inc ...

  7. CodeForces 10D. LCIS 最长公共上升子序列模板题 + 打印路径

    推荐一篇炒鸡赞的blog. 以下代码中有打印路径. #include <algorithm> #include <iostream> #include <cstring& ...

  8. 【简单dp】poj 2127 Greatest Common Increasing Subsequence【最长公共上升子序列】【模板】

    Sample Input 5 1 4 2 5 -12 4 -12 1 2 4 Sample Output 2 1 4 题目:给你两个数字序列,求出这两个序列的最长公共上升子序列.输出最长的长度,并打表 ...

  9. 最长公共上升子序列(LCIS)

    最长公共上升子序列慕名而知是两个字符串a,b的最长公共递增序列,不一定非得是连续的.刚开始看到的时候想的是先用求最长公共子序列,然后再从其中找到最长递增子序列,可是仔细想一想觉得这样有点不妥,然后从网 ...

随机推荐

  1. 理解NLP中的卷积神经网络(CNN)

    此篇文章是Denny Britz关于CNN在NLP中应用的理解,他本人也曾在Google Brain项目中参与多项关于NLP的项目. · 翻译不周到的地方请大家见谅. 阅读完本文大概需要7分钟左右的时 ...

  2. 原生ajax方法封装

    /** * @function ajax request * @fields ajaxName:请求名称,method:请求方法,headers:setRequestHeader自定义部分,url:接 ...

  3. POJ1984:Navigation Nightmare(带权并查集)

    Navigation Nightmare Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 7871   Accepted: 2 ...

  4. 最短路径算法 SP

    dijkstra求最短路径长度 dijkstra求最短路并记录路径 #include<stdio.h> #include<string.h> #include<stack ...

  5. NOIP2005过河(青蛙过河)

    题目传送门 这道题主要是因为L长度最大可以为1e9 而石子却最多只有100个 这样就浪费了很多时间空间 所以我们压缩一波路径就可以了 剩余的就是枚举每个点以及i-y到i-x的dp了 这里要说一句为什么 ...

  6. 【EOJ3654】管理孩子(贪心,二分)

    题意:有一棵n个点的树,其中有k个是关键点,将树分割成若干部分,每部分至少包含一个关键点,求最大分割大小的最小值 思路: 最后特判一下f[1]的值 #include<cstdio> #in ...

  7. system32下 exe文件作用

    system32下EXE文件的作用说明 A accwiz.exe 辅助功能向导 ahui.exe 应用程序兼容用户界面 alg.exe 为 Internet 连接共享和 Internet 连接防火墙提 ...

  8. 教你从头到尾利用DQN自动玩flappy bird(全程命令提示,GPU+CPU版)【转】

    转自:http://blog.csdn.net/v_JULY_v/article/details/52810219?locationNum=3&fps=1 目录(?)[-] 教你从头到尾利用D ...

  9. appium===setup/setupclass的区别,以及@classmathod的使用方法

    一.装饰器 1.用setUp与setUpClass区别 setup():每个测试case运行前运行 teardown():每个测试case运行完后执行 setUpClass():必须使用@classm ...

  10. 使用MXNet远程编写卷积神经网络用于多标签分类

    最近试试深度学习能做点什么事情.MXNet是一个与Tensorflow类似的开源深度学习框架,在GPU显存利用率上效率高,比起Tensorflow显著节约显存,并且天生支持分布式深度学习,单机多卡.多 ...