首先举个例子说明最长上升子序列(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 实现算法的简述的更多相关文章

  1. 最长递减子序列(nlogn)(个人模版)

    最长递减子序列(nlogn): int find(int n,int key) { ; int right=n; while(left<=right) { ; if(res[mid]>ke ...

  2. LCS(最长公共子序列)动规算法正确性证明

    今天在看代码源文件求diff的原理的时候看到了LCS算法.这个算法应该不陌生,动规的经典算法.具体算法做啥了我就不说了,不知道的可以直接看<算法导论>动态规划那一章.既然看到了就想回忆下, ...

  3. 洛谷1439:最长公共子序列(nlogn做法)

    洛谷1439:最长公共子序列(nlogn做法) 题目描述: 给定两个序列求最长公共子序列. 这两个序列一定是\(1\)~\(n\)的全排列. 数据范围: \(1\leq n\leq 10^5\) 思路 ...

  4. 从最长公共子序列问题理解动态规划算法(DP)

    一.动态规划(Dynamic Programming) 动态规划方法通常用于求解最优化问题.我们希望找到一个解使其取得最优值,而不是所有最优解,可能有多个解都达到最优值. 二.什么问题适合DP解法 如 ...

  5. 浅谈最长上升子序列(O(n*logn)算法)

    今天GM讲了最长上升子序列的logn*n算法,但没讲思路... 我看了篇博客,发现-- 说的有道理!!! 首先,举例子: a[7]={1,2,4,3,6,7,5}(假设以1开头) 很明显,LIS=5: ...

  6. (转载)最长递增子序列 O(NlogN)算法

    原博文:传送门 最长递增子序列(Longest Increasing Subsequence) 下面我们简记为 LIS. 定义d[k]:长度为k的上升子序列的最末元素,若有多个长度为k的上升子序列,则 ...

  7. 最长递增子序列 O(NlogN)算法

    转自:点击打开链接 最长递增子序列,Longest Increasing Subsequence 下面我们简记为 LIS. 排序+LCS算法 以及 DP算法就忽略了,这两个太容易理解了. 假设存在一个 ...

  8. 最长上升子序列O(nlogn)算法详解

    最长上升子序列 时间限制: 10 Sec   内存限制:128 MB 题目描述 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.我们想知道此时最长上升子 ...

  9. P3402 最长公共子序列(nlogn)

    P3402 最长公共子序列 题目背景 DJL为了避免成为一只咸鱼,来找Johann学习怎么求最长公共子序列. 题目描述 经过长时间的摸索和练习,DJL终于学会了怎么求LCS.Johann感觉DJL孺子 ...

随机推荐

  1. Leetcode690.Employee Importance员工的重要性

    给定一个保存员工信息的数据结构,它包含了员工唯一的id,重要度 和 直系下属的id. 比如,员工1是员工2的领导,员工2是员工3的领导.他们相应的重要度为15, 10, 5.那么员工1的数据结构是[1 ...

  2. BootstrapValidation一些tips

    BootstrapValidation一些tips:1. callback的用法 如果你有一些特别的检查需要,比如两个元素必需有一个有值,你可以在两个元素上加上callback,例:sel和cb必需有 ...

  3. 如何使我们的薪资15k?

    以下我们来探讨一下如何才能使我们具备高薪15K的能力? 要想使自己的薪资成为15K,我首先想到的是我们的能力?编码能力?语言表达能力? 我觉得为之重要的则是我们的综合能力: 方方面面的能力.综合素质: ...

  4. linux 下配置多个tomcat同时运行

    一个服务器上内存通常有2G或者更多,一个tomcat 运行管理这么多内存有点力不从心,并且貌似一个进程所能建立的线程数量是有限的,于是我们想要在一个服务器上运行多个tomcat.如下是摘抄自:http ...

  5. jquery全屏图片滑动切换

    在线演示 本地下载

  6. 重磅!容器集群监控利器 阿里云Prometheus 正式免费公测

    Prometheus 作为容器生态下集群监控的首选方案,是一套开源的系统监控报警框架.它启发于 Google 的 borgmon 监控系统,并于 2015 年正式发布.2016 年,Prometheu ...

  7. qbao

    # -*- coding: utf-8 -*- import Image, cStringIO, webbrowser, re, time, math import urllib, urllib2, ...

  8. centos6.5后台进程的切换

    1.运行.sh文件 直接用./sh 文件就可以运行,但是如果想后台运行,即使关闭当前的终端也可以运行的话,需要nohup命令和&命令. (1)&命令 功能:加在一个命令的最后,可以把这 ...

  9. python 并发之线程

    一.什么是线程 #指的是一条流水线的工作过程,关键的一句话:一个进程内最少自带一个线程,其实进程根本不能执行,进程不是执行单位,是资源的单位,分配资源的单位 #线程才是执行单位 #进程:做手机屏幕的工 ...

  10. cocos2dx 2.2.3在Windows 7 64bit上搭建开发环境

    最终弄完了cocos2dx 2.2.3在windows 7 64bit上的环境搭建,过程比較揪心.揪心的主要原因还是引擎的开发人员和官方文档的写作者都是偏爱MAC OS的,所以官方文档中的安装方法是以 ...