最长上升子序列问题 nlogn 实现算法的简述
首先举个例子说明最长上升子序列(longest increasing subsequence 缩写 LIS):
1,4,6,2,3,7,5 中1,2,3,5 和1,4,6,7都是最长上升子序列,长度均为4,且相邻元素不能相等。
LIS是动态规划中的经典问题,O(n2)的做法是设d(i)为以i为结尾的最长上升子序列的长度,状态转移方程为:d[i]=max{0,d[j]|j<i,A[j]<A[i]}+1。
下面我们仔细思考以下情况:
i<j时,d[i]=d[j],显然这种情况只能是A[i]>=A[j];这时我们计算 d[t](t>j且A[t]>A[i]),那么应优先选取以A[j]结尾的子序列作为A[t]的前缀序列,因为如果存在
i<j<z<t,满足A[j]<A[z]<A[i]<A[t],子序列的长度会因z的存在而增加。
由此我们使用数组D[k]保存满足d[t]=k的最小A[t],即D[k]=min{A[t]|d[t]=k};
可以证明D[k]是严格单调递增的,即D[1]<D[2]<D[3]<……<D[len],
证明如下:
D[k]=min{A[t1]|d[t1]=k};
D[k+1]=min{A[t2]|d[t2]=k+1};
采用反证法,
令A[t1]=D[k],A[t2]=D[k+1]
假设A[t2]<A[t1];
设以A[t2]结尾对应的子序列为S[1]~S[k],A[t2], 满足S[k]<A[t2].
显然S[1]~S[k]是一个以S[k]为结尾的最长上升子序列,长度为k,
则有A[t1]=D[k]<=S[k]<A[t2],与假设矛盾,故D为严格单调递增序列。
于是利用D我们可以得到另外一种计算最长上升子序列的方法,并且可以边读边计算D,算法如下:
1)设当前最大子序列长度为len,读入A[i];
2)如果A[i]>D[len],则len++,D[len]=A[i];
3)如果A[i]<=D[len],则从1~len中二分查找第一个k,使D[k]>=A[i],更新D[k]=A[i].
代码如下:
int n;//原序列长度
cin>>n;
memset(A, ,sizeof A);
memset(D, , sizeof D);
int len=;//当前最长子序列长度
for(int i=;i<n;i++){
cin>>A[i];
if(A[i]>D[len]){
len++;
D[len]=A[i];
}
else {
int k=lower_bound(D, D+len, A[i])-D;//二分搜索D[k]>=A[i],更新D[k]
D[k]=A[i];
}
}
cout<<len<<endl;
return ;
最长上升子序列问题 nlogn 实现算法的简述的更多相关文章
- 最长递减子序列(nlogn)(个人模版)
最长递减子序列(nlogn): int find(int n,int key) { ; int right=n; while(left<=right) { ; if(res[mid]>ke ...
- LCS(最长公共子序列)动规算法正确性证明
今天在看代码源文件求diff的原理的时候看到了LCS算法.这个算法应该不陌生,动规的经典算法.具体算法做啥了我就不说了,不知道的可以直接看<算法导论>动态规划那一章.既然看到了就想回忆下, ...
- 洛谷1439:最长公共子序列(nlogn做法)
洛谷1439:最长公共子序列(nlogn做法) 题目描述: 给定两个序列求最长公共子序列. 这两个序列一定是\(1\)~\(n\)的全排列. 数据范围: \(1\leq n\leq 10^5\) 思路 ...
- 从最长公共子序列问题理解动态规划算法(DP)
一.动态规划(Dynamic Programming) 动态规划方法通常用于求解最优化问题.我们希望找到一个解使其取得最优值,而不是所有最优解,可能有多个解都达到最优值. 二.什么问题适合DP解法 如 ...
- 浅谈最长上升子序列(O(n*logn)算法)
今天GM讲了最长上升子序列的logn*n算法,但没讲思路... 我看了篇博客,发现-- 说的有道理!!! 首先,举例子: a[7]={1,2,4,3,6,7,5}(假设以1开头) 很明显,LIS=5: ...
- (转载)最长递增子序列 O(NlogN)算法
原博文:传送门 最长递增子序列(Longest Increasing Subsequence) 下面我们简记为 LIS. 定义d[k]:长度为k的上升子序列的最末元素,若有多个长度为k的上升子序列,则 ...
- 最长递增子序列 O(NlogN)算法
转自:点击打开链接 最长递增子序列,Longest Increasing Subsequence 下面我们简记为 LIS. 排序+LCS算法 以及 DP算法就忽略了,这两个太容易理解了. 假设存在一个 ...
- 最长上升子序列O(nlogn)算法详解
最长上升子序列 时间限制: 10 Sec 内存限制:128 MB 题目描述 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.我们想知道此时最长上升子 ...
- P3402 最长公共子序列(nlogn)
P3402 最长公共子序列 题目背景 DJL为了避免成为一只咸鱼,来找Johann学习怎么求最长公共子序列. 题目描述 经过长时间的摸索和练习,DJL终于学会了怎么求LCS.Johann感觉DJL孺子 ...
随机推荐
- 阿里云ecs环境配置
在阿里云 CentOS 服务器(ECS)上搭建 nginx + mysql + php-fpm 环境 https://ninghao.net/blog/1368 阿里云ecs从购买到环境搭建和建站!! ...
- 【水滴石穿】FirstReactNativeProject
这个是一个小demo,项目地址为https://github.com/prsioner/FirstReactNativeProject 有注册,忘记密码还有登陆,应该是用到了react-navigat ...
- JavaScript--漏写var却还能使用标签
一个漏写var带来的问题: 这个是不标准的写法!不建议使用 但是效果还是出来了,为什么呢? 原因: https://zhidao.baidu.com/question/1637589020484843 ...
- sed 命令用法
Sed:对文件进行编辑操作,对象是行.操作后在屏幕输出结果.如果要直接修改则加-i命令-f filename: 执行某文件内的sed命令-n 只显示被修改的那一行 如文件test内容:Letyou a ...
- php的一些误解
1.php函数和方法是不用的:类的方法可以设定访问权限,需要通过对象或者类来调用:函数是公共的,都可以使用.
- 2019-6-23-WPF-网络-request-的-read-方法不会返回
title author date CreateTime categories WPF 网络 request 的 read 方法不会返回 lindexi 2019-06-23 11:26:26 +08 ...
- php代码在模板页的活用
- WPF中的简单水动画
原文 https://stuff.seans.com/2008/08/21/simple-water-animation-in-wpf/ 很多年前(80年代中期),我在一家拥有Silicon Grap ...
- Python 常量
- HZOJ 随
这个题的题解并不想写……一个写的很详细的blog 第1个测试点:mod=2,a[i]<mod(仔细看题),则n个数字都是1,直接输出1即可. 第2个测试点:每次乘上去的数字只有一种选择,快速幂即 ...