最长上升子序列问题 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孺子 ...
随机推荐
- matplotlib常用操作
1.根据坐标点绘制: import numpy as np import matplotlib.pyplot as plt x = np.array([1,2,3,4,5,6,7,8]) y = np ...
- 单行中文字和图片的相关height和line-height特性
这几天在做仿京东的产品页,发现在制作过程中的一些问题,需要好好研究下. 需要实现的效果如上图所示: 在写CSS样式的时候,对于我的关于竖线的做法是: 设置高度为14,border样式,但导致了一个问题 ...
- class介绍
ES6引入了Class(类)这个概念,作为对象的模板.通过class关键字,可以定义类.基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对 ...
- vagrant up 时提示错误 cound not open file
根据教程:https://laravel-china.org/docs/laravel-development-environment/5.5/development-environment-wind ...
- 数据挖掘算法R语言实现之决策树
数据挖掘算法R语言实现之决策树 最近,看到很多朋友问我如何用数据挖掘算法R语言实现之决策树,想要了解这方面的内容如下: > library("party")导入数据包 > ...
- day39-Spring 03-JDK的动态代理
package cn.itcast.spring3; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Meth ...
- 【JZOJ4886】【NOIP2016提高A组集训第13场11.11】字符串
题目描述 某日mhy12345在教同学们写helloworld,要求同学们用程序输出一个给定长度的字符串,然而发现有些人输出了一些"危险"的东西,所以mhy12345想知道对于任意 ...
- poj3294 后缀数组
后缀数组多个字符串问题. 先求出height[]数组,然后二分求最大的长度. 但是条件需要改变.如果出现次数大于一般那就满足.然后就要解决如何判断那一段属于其中一个字符串. 所以先处理出长度.并且不断 ...
- Java8 日期、时间操作
一.简介 在Java8之前,日期时间API一直被开发者诟病,包括:java.util.Date是可变类型,SimpleDateFormat非线程安全等问题.故此,Java8引入了一套全新的日期时间处理 ...
- Oracle事物处理
n 什么是事物 事物是把对数据库的一系列操作(dml)看做一个整体 事物用于保证数据的一致性,它由一组相关的dml语句组成,改组的dml语句要么全部成功,要么全部失败. 如:网上转账就是典型的要用事 ...