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 简单记录一下自己学的: 问题就是求一个数列最长上升子序列的长度 ...
随机推荐
- RecycleView设置顶部分割线(记录一个坑)
大家都知道,想给RecycleView设置分割线可以重写RecyclerView.ItemDecoration 项目过程中,遇到一个需求:RecycleView顶部有一条灰色的间隔,我想到了给Recy ...
- idea部署Maven入门(一)——环境变量的配置和下载
介绍: 1 Maven是用来管理jar包的一种工具, 2 Maven主要是构建java项目和java web项目 3 maven项目管理所依赖的jar ...
- C#基础第七天
1.ref参数ref参数侧重于将一个变量以参数的形式带到一个方法中进行改变,改变完成后,再讲改变后的值带出来.在使用ref参数的时候需要注意:ref参数在方法外必须为其赋值. 2.方法的重载方法的重载 ...
- (转)聊聊Greenplum的那些事
开卷有益——作者的话 有时候真的感叹人生岁月匆匆,特别是当一个IT人沉浸于某个技术领域十来年后,蓦然回首,总有说不出的万千感慨. 笔者有幸从04年就开始从事大规模数据计算的相关工作,08年作为Gree ...
- 【原】Java学习笔记017 - 面向对象
package cn.temptation; public class Sample01 { public static void main(String[] args) { // 继承关系中的pri ...
- LeetCode算法题-Quad Tree Intersection(Java实现)
这是悦乐书的第260次更新,第273篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第127题(顺位题号是558).四叉树是树数据,其中每个内部节点恰好有四个子节点:top ...
- HybridStart混合应用开发框架
转自我的博客,原文地址:http://refined-x.com/2017/06/26/%E5%9F%BA%E4%BA%8EAPICloud%E7%9A%84%E6%B7%B7%E5%90%88%E5 ...
- Python 函数调用&定义函数&函数参数
一.函数调用 在python中内置了很多函数,我们可以直接调用 .想要调用函数首先要知道函数的名称及包含的参数,还可以通过查看python官方的文档:https://docs.python.org/3 ...
- linux环境下快速安装Mariadb和Redis
一 Mariadb(Mysql)篇 1.新建一个yum源仓库 touch /etc/yum.repos.d/Mariadb.repo 2.在这个yum源仓库文件中,添加仓库url地址 [mariadb ...
- Linux 进入 5.0 时代!
Linux 进入 5.0 时代! 为什么 Linux 4.2 之后的版本不再是 4.21 而是 5.0? 如果你非要一个理由,那就是因为 Linux 4.x 的版本如今用手指与脚趾加在一起都要数不过来 ...