时间复杂度为〇(nlogn)的算法,下面就来看看。

我们再举一个例子:有以下序列A[]=3 1 2 6 4 5 10 7,求LIS长度。

我们定义一个B[i]来储存可能的排序序列,len为LIS长度。我们依次把A[i]有序地放进B[i]里。(为了方便,i的范围就从1~n表示第i个数)

A[1]=3,把3放进B[1],此时B[1]=3,此时len=1,最小末尾是3

A[2]=1,因为1比3小,所以可以把B[1]中的3替换为1,此时B[1]=1,此时len=1,最小末尾是1

A[3]=2,2大于1,就把2放进B[2]=2,此时B[]={1,2},len=2

同理,A[4]=6,把6放进B[3]=6,B[]={1,2,6},len=3

A[5]=4,4在2和6之间,比6小,可以把B[3]替换为4,B[]={1,2,4},len=3

A[6]=5,B[4]=5,B[]={1,2,4,5},len=4

A[7]=10,B[5]=10,B[]={1,2,4,5,10},len=5

A[8]=7,7在5和10之间,比10小,可以把B[5]替换为7,B[]={1,2,4,5,7},len=5

最终我们得出LIS长度为5。但是,但是!!这里的1 2 4 5 7很明显并不是正确的最长上升子序列。是的,B序列并不表示最长上升子序列,它只表示相应最长子序列长度的排好序的最小序列。这有什么用呢?我们最后一步7替换10并没有增加最长子序列的长度,而这一步的意义,在于记录最小序列,代表了一种“最可能性”。假如后面还有两个数据8和9,那么B[6]将更新为8,B[7]将更新为9,len就变为7

lower_bound(a,a+n,i)函数 返回从数组a到a+n中第一个>=i的元素地址

upper_bound(a,a+n,i)函数 返回从数组a到a+n中第一个>i的元素地址

#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=;
int a[MAXN];
int d[MAXN];
int main()
{
int n;
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
d[]=a[];
int len=;
for(int i=;i<=n;i++)
{
if(a[i]>d[len])
d[++len]=a[i];
else
{
int j=lower_bound(d+,d+len+,a[i])-d;
d[j]=a[i];
}
}
printf("%d\n",len);
return ;
}

动态规划-最长上升子序列(LIS)的更多相关文章

  1. 动态规划——最长上升子序列LIS及模板

    LIS定义 一个数的序列bi,当b1 < b2 < … < bS的时候,我们称这个序列是上升的.对于给定的一个序列(a1, a2, …, aN),我们可以得到一些上升的子序列(ai1 ...

  2. 算法之动态规划(最长递增子序列——LIS)

    最长递增子序列是动态规划中最经典的问题之一,我们从讨论这个问题开始,循序渐进的了解动态规划的相关知识要点. 在一个已知的序列 {a1, a 2,...an}中,取出若干数组成新的序列{ai1, ai ...

  3. 动态规划 - 最长递增子序列(LIS)

    最长递增子序列是动态规划中经典的问题,详细如下: 在一个已知的序列{a1,a2,...,an}中,取出若干数组组成新的序列{ai1,ai2,...,aim},其中下标i1,i2,...,im保持递增, ...

  4. 动态规划--最长上升子序列(LIS)的长度

    l例如:对于[3,1,4,2,5],最长上升子序列的长度是3 arr = [3,1,4,5,9,2,6,5,0] def lis(arr): #dp[i]表示第i个位置的值为尾的数组的最长递增子序列的 ...

  5. 动态规划(DP),最长递增子序列(LIS)

    题目链接:http://poj.org/problem?id=2533 解题报告: 状态转移方程: dp[i]表示以a[i]为结尾的LIS长度 状态转移方程: dp[0]=1; dp[i]=max(d ...

  6. nlog(n)解动态规划--最长上升子序列(Longest increasing subsequence)

    最长上升子序列LIS问题属于动态规划的初级问题,用纯动态规划的方法来求解的时间复杂度是O(n^2).但是如果加上二叉搜索的方法,那么时间复杂度可以降到nlog(n).  具体分析参考:http://b ...

  7. 2.16 最长递增子序列 LIS

    [本文链接] http://www.cnblogs.com/hellogiser/p/dp-of-LIS.html [分析] 思路一:设序列为A,对序列进行排序后得到B,那么A的最长递增子序列LIS就 ...

  8. 最长回文子序列LCS,最长递增子序列LIS及相互联系

    最长公共子序列LCS Lintcode 77. 最长公共子序列 LCS问题是求两个字符串的最长公共子序列 \[ dp[i][j] = \left\{\begin{matrix} & max(d ...

  9. 最长上升子序列LIS(51nod1134)

    1134 最长递增子序列 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 给出长度为N的数组,找出这个数组的最长递增子序列.(递增子序列是指,子序列的元素是递 ...

随机推荐

  1. C# 之 HttpRequest 类

          Request对象派生自HttpRequest类,使 ASP.NET 能够读取客户端在 Web 请求期间发送的 HTTP 值,从客户端获取信息,浏览器的种类,用户输入表单的数据,Cooki ...

  2. python基础——高级特性

    1.切片  切片: >>> L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack'] >>> L[:3] ['Michael ...

  3. node.js版本管理

    Node安装 Node的安装需要依赖很多,如gcc等,首先我们需要将这些安装成功,用rpm命令查看下,果然我们并没有gcc等,所以要用yum进行安装(基于centos6.9版本): yum -y in ...

  4. 经典的XSS案例

    在做安全审计的时候,通过常用的<script>alert(1)</script>无法发现该XSS

  5. 通过ping命令查看服务器是linux还是windows系列

    通过ping命令识别服务器类型

  6. Centos7创建CA和申请证书

    转载:http://rackie386.blog.51cto.com/11279229/1947999 Centos7.3创建CA和申请证书 openssl 的配置文件:/etc/pki/tls/op ...

  7. linux系统虚拟机下安装jdk

    首先需要得到可以创建文件和上传文件的权限 . 将下载好的jdk文件上传到指定的文件目录下. tar -zxvf        jdk-8u60-linux-x64.tar.gz 解压到当前文件下  会 ...

  8. 03. Pandas 2| 时间序列

    1.时间模块:datetime datetime模块,主要掌握:datetime.date(), datetime.datetime(), datetime.timedelta() 日期解析方法:pa ...

  9. MATLAB的一些使用的快捷键整理

    1.用TAB键可以实现缩进,怎么缩进和取消缩进呢? 在使用脚本编写matlab的程序时,我们通过选中需要的程序,按下tab键就能缩进整个程序.同样的,当我们需要取消缩进时,我们的快捷方法就是:shif ...

  10. type__列表