【题目描述】

给定N个数,求这N个数的最长上升子序列的长度。

【样例输入】

7

2 5 3 4 1 7 6

【样例输出】

4

什么是最长上升子序列? 就是给你一个序列,请你在其中求出一段不断严格上升的部分,它不一定要连续。

就像这样:2,3,4,7和2,3,4,6就是序列2 5 3 4 1 7 6的两种选取方案。最长的长度是4.

什么是最长上升子序列? 就是给你一个序列,请你在其中求出一段不断严格上升的部分,它不一定要连续。

就像这样:2,3,4,7和2,3,4,6就是序列2 5 3 4 1 7 6的两种选取方案。最长的长度是4.

思路:

新建一个low数组,low[i]表示长度为i的LIS结尾元素的最小值。对于一个上升子序列,显然其结尾元素越小,越有利于在后面接其他的元素,也就越可能变得更长。因此,我们只需要维护low数组,对于每一个a[i],如果a[i] > low[当前最长的LIS长度],就把a[i]接到当前最长的LIS后面,即low[++当前最长的LIS长度]=a[i]。 

那么,怎么维护low数组呢? 

对于每一个a[i],如果a[i]能接到LIS后面,就接上去;否则,就用a[i]取更新low数组。具体方法是,在low数组中找到第一个大于等于a[i]的元素low[j],用a[i]去更新low[j]。如果从头到尾扫一遍low数组的话,时间复杂度仍是O(n^2)。我们注意到low数组内部一定是单调不降的,所有我们可以二分low数组,找出第一个大于等于a[i]的元素。二分一次low数组的时间复杂度的O(lgn),所以总的时间复杂度是O(nlogn)。

代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <cmath>
using namespace std;
const int maxn =300003,INF=0x7f7f7f7f;
int low[maxn],a[maxn];
int n,ans;
int binary_search(int *a,int r,int x)
//二分查找,返回a数组中第一个>=x的位置
{
int l=1,mid;
while(l<=r)
{
mid=(l+r)>>1;
if(a[mid]<=x)
l=mid+1;
else
r=mid-1;
}
return l;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
low[i]=INF;//由于low中存的是最小值,所以low初始化为INF
}
low[1]=a[1];
ans=1;//初始时LIS长度为1
for(int i=2;i<=n;i++)
{
if(a[i]>=low[ans])//若a[i]>=low[ans],直接把a[i]接到后面
low[++ans]=a[i];
else //否则,找到low中第一个>=a[i]的位置low[j],用a[i]更新low[j]
low[binary_search(low,ans,a[i])]=a[i];
}
printf("%d\n",ans);//输出答案
return 0;
}

最长子序列问题(二分+贪心nlogn算法)的更多相关文章

  1. hdu 1950 Bridging signals 求最长子序列 ( 二分模板 )

    Bridging signals Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  2. 最长不下降序列nlogn算法

    显然n方算法在比赛中是没有什么用的(不会这么容易就过的),所以nlogn的算法尤为重要. 分析: 开2个数组,一个a记原数,f[k]表示长度为f的不下降子序列末尾元素的最小值,tot表示当前已知的最长 ...

  3. 算法-最长子序列和C/C++实现(三个复杂度)

    最长子序列和的问题非常easy: 就是一个数组,求出当中当中连续的某一段和,而这一段和是全部的连续段和的最大的值.求出这个值. 先说复杂度最高的:O(n3) 直接上代码,非常easy的: // // ...

  4. nyoj 17-单调递增最长子序列 && poj 2533(动态规划,演算法)

    17-单调递增最长子序列 内存限制:64MB 时间限制:3000ms Special Judge: No accepted:21 submit:49 题目描述: 求一个字符串的最长递增子序列的长度 如 ...

  5. 算法:Common Subsequence(动态规划 Java 最长子序列)

    Description A subsequence of a given sequence is the given sequence with some elements (possible non ...

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

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

  7. 最长不下降子序列nlogn算法详解

    今天花了很长时间终于弄懂了这个算法……毕竟找一个好的讲解真的太难了,所以励志我要自己写一个好的讲解QAQ 这篇文章是在懂了这个问题n^2解决方案的基础上学习. 解决的问题:给定一个序列,求最长不下降子 ...

  8. POJ 1631 Bridging signals(LIS O(nlogn)算法)

    Bridging signals Description 'Oh no, they've done it again', cries the chief designer at the Waferla ...

  9. 最长上升子序列(LIS)长度的O(nlogn)算法

    最长上升子序列(LIS)的典型变形,熟悉的n^2的动归会超时.LIS问题可以优化为nlogn的算法.定义d[k]:长度为k的上升子序列的最末元素,若有多个长度为k的上升子序列,则记录最小的那个最末元素 ...

随机推荐

  1. 基于Flask框架的Python web程序的开发实战 <二> 项目组织结构

    看到第七章-大型程序的结构,备受打击,搞不清工厂函数.蓝本.单元测试,不理解这些对象/变量怎么传递的,感觉好乱,虽然按照源码都照抄了,还是不理解.... 缓缓先.... 本来网上的Flask的教程就比 ...

  2. 向linux内核增加一个系统调用-1

    验证编辑编译内核的流程,并增加新的系统调用 注意:需要/目录至少10GB空间,/boot目录500MB空间 下载内核并解压 kernel下载 百度云搬运 密码: qc8b 进入 /usr/src目录 ...

  3. matlab读取excel

    xlsread函数: x = xlsread('d:/min1.csv','B2:B10');    %文件名和路径:所读取的数据范围:

  4. DOM详习讲解

    http://www.cnblogs.com/wupeiqi/articles/5643298.html 

  5. ubuntu16安装pylearn2 出现错误提示importerror:no module named six.moves

    由于市面上的一些教程时间比较早,入门学习时跟随教程安装容易出现各种错误,这些错误基本都是版本不同导致的 所以,我们安装过程中一定要指出包的版本,如果你已经遇到no module named six.m ...

  6. alias这个命令还是很有用的

    这是在知乎看到的一个回答. 我一开始学习linux命令的时候觉得这个alias命令很奇怪,为什么要给别人起个别名呢?有什么好处? 因为当时接触的是比较简单的命令 比如ls -al的这种短小的命令,对a ...

  7. AbstractFactoryPattern(23种设计模式之一)

    设计模式六大原则(1):单一职责原则 设计模式六大原则(2):里氏替换原则 设计模式六大原则(3):依赖倒置原则 设计模式六大原则(4):接口隔离原则 设计模式六大原则(5):迪米特法则 设计模式六大 ...

  8. GCD学习(七) dispatch_apply

    dispathc_apply 是dispatch_sync 和dispatch_group的关联API.它以指定的次数将指定的Block加入到指定的队列中.并等待队列中操作全部完成. NSArray ...

  9. 树莓派研究笔记(7)-- lakka 《仙剑奇侠传》的完美移植

    仙剑,这是我玩的第一个电脑游戏.真的太经典,无法超越.原来第一次玩的缺少开场动画,很多地方不明不白的.现在终于我们可以把这个梦想继续到树莓派中. LAKKA是支持DOS模拟器的,所以我们一定要下载DO ...

  10. boost::python的使用

    boost::python库是pyhon和c++相互交互的框架,可以再python中调用c++的类和方法,也可以让c++调用python的类和方法   python自身提供了一个Python/C AP ...