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 简单记录一下自己学的: 问题就是求一个数列最长上升子序列的长度 ...
随机推荐
- CSS Grid 布局完全指南(图解 Grid 详细教程)
CSS Grid 布局是 CSS 中最强大的布局系统.与 flexbox 的一维布局系统不同,CSS Grid 布局是一个二维布局系统,也就意味着它可以同时处理列和行.通过将 CSS 规则应用于 父元 ...
- arcgis api 3.x for js 入门开发系列十一地图统计图(附源码下载)
前言 关于本篇功能实现用到的 api 涉及类看不懂的,请参照 esri 官网的 arcgis api 3.x for js:esri 官网 api,里面详细的介绍 arcgis api 3.x 各个类 ...
- [翻译] Oracle Database 12c 新特性Multitenant
译自官方白皮书http://www.oracle.com/technetwork/database/plug-into-cloud-wp-12c-1896100.pdf,包含新的云计算相关技术的介绍. ...
- 使用python操作XML增删改查
使用python操作XML增删改查 什么是XML? XML 指可扩展标记语言(EXtensible Markup Language) XML 是一种标记语言,很类似 HTML XML 的设计宗旨是传输 ...
- IPD体系向敏捷开发模式转型实施成功的四个关键因素
文/杨学明 集成产品开发(IPD).集成能力成熟度模型(CMMI).敏捷开发(Agile Development)是当前国内外企业产品研发管理的最常用的3种模式.随着创新环境的快速发展,许多企业都会 ...
- 在coding或者github建立个人站点域名绑定
coding:静态的在域名服务器与是填写pages.coding.me,不是填写{你的名字}.coding.me A型的ip是ping 该域名ip github:上传大项目可能报错(报错名字忘记了), ...
- 我的第一个python web开发框架(32)——定制ORM(八)
写到这里,基本的ORM功能就完成了,不知大家有没有发现,这个ORM每个方法都是在with中执行的,也就是说每个方法都是一个完整的事务,当它执行完成以后也会将事务提交,那么如果我们想要进行一个复杂的事务 ...
- sqlalchemy外键的一些东西
sqlalchemy中让MySQL支持中文字符 engine = create_engine("mysql+pymysql://root:mysql8@localhost/mysqltest ...
- 【English】20190416
anti-money laundering反洗钱[ˈænti][ˈlɔːndərɪŋ] misconduct不当行为[ˌmɪsˈkɑːndʌkt] Currently, she is focus ...
- Git命令行管理代码、安装及使用
出处:https://www.cnblogs.com/ximiaomiao/p/7140456.html Git安装和使用 目的:通过Git管理github托管项目代码 一.下载安装Git 1 ...