LIS的O(nlogn)算法
出自蓝书《算法竞赛入门经典训练指南》
求最长上升子序列是很常见的可以用动态规划解决的问题……
很容易根据最优子结构之类的东西得出
$\text{dp}[i]$为以第i个数结尾的最长上升子序列长度
定义$\max{\emptyset}=0$,粗略地写出
\[\text{dp}[i] = \max \left\{ \text{dp}[j]|0\leqslant j < i,A[j] < A[i] \right\} + 1\]
状态数$\mathcal{O}({n})$,如果直接枚举转移,转移数$\mathcal{O}({n})$,时间复杂度$\mathcal{O}({n^2})$
现在想办法加速转移……
设$\text{dp}^{-1}[x]$为$x=\text{dp}[i]$中$\text{A}[i]$最小的$i$
设$\text{pd}[x]=\text{A}[\text{dp}^{-1}[x]]$
若有$\text{A}[i]<\text{A}[j]$且$\text{dp}[i]==\text{dp}[j]$,那么之后的元素只需要比$\text{A}[i]=\text{pd}[x]=\text{pd}[\text{dp}[i]]$大就可以用$\text{dp}[i]$进行转移
很容易得\[\text{pd}[1]\leqslant \text{pd}[2]\leqslant \text{pd}[3]\leqslant \cdots \leqslant \text{pd}[n] \tag{1}\label{1} \]
\[\text{dp}[i]=\max\left\{x|0\leqslant j < i,\text{pd}[x]<A[i]\right\}+1\]
即最大的小于A[i]的下标加1,也就等价于最小的大于等于A[i]的下标,设为$k$ $\tag{2}\label{2}$

因为最后$[l,r)$区间收缩到$\emptyset$时左侧区间最后一个元素加一就是右侧区间第一个元素
用STL的lower_bound就不需要自己写二分了
因为$\eqref{1}\eqref{2}$,所以$A[i]\leqslant \text{pd}[k]$,转移以后需要更新$\text{pd}[k]$
但是之前少考虑了$0\leqslant j < i$,只需将未计算的$\text{pd}[x]$设为INF就好了= =
时间复杂度$\mathcal{O}(n\log n)$
代码
REPE(i,1,n) pd[i]=INF;
REP(i,0,n) {
int k=lower_bound(pd+1,pd+1+n,A[i])-g;
dp[i]=k;
pd[k]=A[i];
}
很容易得最长非降子序列只需将lower_bound改为upper_bound(同样照着二分的参考图)
然后最长下降子序列只需添加greater<int>()参数,并且初始化为-INF
注意dp为以第i个数结尾的长度,所以求最长还需求一遍max
LIS的O(nlogn)算法的更多相关文章
- POJ 1631 Bridging signals(LIS O(nlogn)算法)
Bridging signals Description 'Oh no, they've done it again', cries the chief designer at the Waferla ...
- 最长上升子序列(LIS)长度的O(nlogn)算法
最长上升子序列(LIS)的典型变形,熟悉的n^2的动归会超时.LIS问题可以优化为nlogn的算法.定义d[k]:长度为k的上升子序列的最末元素,若有多个长度为k的上升子序列,则记录最小的那个最末元素 ...
- 最长递增子序列 O(NlogN)算法
转自:点击打开链接 最长递增子序列,Longest Increasing Subsequence 下面我们简记为 LIS. 排序+LCS算法 以及 DP算法就忽略了,这两个太容易理解了. 假设存在一个 ...
- 最长不下降子序列的O(n^2)算法和O(nlogn)算法
一.简单的O(n^2)的算法 很容易想到用动态规划做.设lis[]用于保存第1~i元素元素中最长不下降序列的长度,则lis[i]=max(lis[j])+1,且num[i]>num[j],i&g ...
- 最长上升子序列O(nlogn)算法详解
最长上升子序列 时间限制: 10 Sec 内存限制:128 MB 题目描述 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.我们想知道此时最长上升子 ...
- 连续子序列最大和的O(NlogN)算法
对于一个数组,例如:int[] a = {4,-3,5,-2,-1,2,6,-2}找出一个连续子序列,对于任意的i和j,使得a[i]+a[i+1]+a[i+2]+.......+a[j]他的和是所有子 ...
- 浅析拯救小矮人的 nlogn 算法及其证明
浅析拯救小矮人的 nlogn 算法及其证明 题型简介: 有 $ n $ 个人,第 $ i $ 个人身高 $ a_i $ 手长 $ b_i $ ,他们为了从一个高为 $ H $ 的洞中出去,决定搭人梯. ...
- 最长上升子序列(LIS)n2 nlogn算法解析
题目描述 给定一个数列,包含N个整数,求这个序列的最长上升子序列. 例如 2 5 3 4 1 7 6 最长上升子序列为 4. 1.O(n2)算法解析 看到这个题,大家的直觉肯定都是要用动态规划来做,那 ...
- hdu 1950 最长上升子序列(lis) nlogn算法【dp】
这个博客说的已经很好了.http://blog.csdn.net/shuangde800/article/details/7474903 简单记录一下自己学的: 问题就是求一个数列最长上升子序列的长度 ...
随机推荐
- 原生js实现数据单向绑定
Object.defineProperty()方法直接在对象上定义一个新属性,或修改对象上的现有属性,并返回该对象. Object.defineProperty(obj, prop, descript ...
- Bootstrap方法之--排版、代码
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8& ...
- JavaScript知识点 思维导图
javascript变量 javascript数据类型 javascript运算符 javascript流程语句 javascript数组 javascript字符串函数 javascript函数基础 ...
- TextView图文混排
大家都知道,textView有一个setCompoundDrawables的方法来设置上下左右位置的图标,当然,也可以在xml布局文件中设置,然而问题来了,假如我们把图标放在左边,当我们让TextVi ...
- QT 启动shell脚本
1.QProcess *p = new QProcess(this); 2.QString str = qApp->applicationDirPath() + "/update.sh ...
- 【English】二、It作为代词,可以代指什么
it的用法 一.用作人称代词: 1.指代事物: — What’s this? — It’s a cat.2.指代人:常用于不知对方性别时,比如:询问敲门人或打电话时询问对方是谁,或者用来指代婴儿. ( ...
- spring学习总结——高级装配学习四(运行时:值注入、spring表达式)
前言: 当讨论依赖注入的时候,我们通常所讨论的是将一个bean引用注入到另一个bean的属性或构造器参数中.bean装配的另外一个方面指的是将一个值注入到bean的属性或者构造器参数中.在没有学习使用 ...
- Word Count作业
Word Count作业 一.个人Gitee地址:https://gitee.com/Changyu-Guo 二.项目简介 该项目主要是模拟Linux上面的wc命令,基本要求如下: 命令格式: wc. ...
- SQLServer之触发器简介
触发器定义 触发器是数据库服务器中发生事件时自动执行的一种特殊存储过程.SQLServer允许为任何特定语句创建多个触发器.它的执行不是由程序调用,也不是手工启动,而是由事件来触发,当对数据库进行操作 ...
- git冲突解决办法合集
一 换行符CRLF错误解决办法 1 错误产生原因 不同的操作系统使用的换行符是不一样的. unix/linux使用的是LF,max后期也采用了LF,但在windows一直采用的CRLF(回车)换行符. ...