单调递增子序列(二)

时间限制:1000 ms  |  内存限制:65535 KB
难度:4
描写叙述

给定一整型数列{a1,a2...,an}(0<n<=100000)。找出单调递增最长子序列,并求出其长度。

如:1 9 10 5 11 2 13的最长单调递增子序列是1 9 10 11 13,长度为5。

输入
有多组測试数据(<=7)

每组測试数据的第一行是一个整数n表示序列中共同拥有n个整数,随后的下一行里有n个整数,表示数列中的全部元素.每一个整形数中间用空格间隔开(0<n<=100000)。

数据以EOF结束 。

输入数据保证合法(全为int型整数)!
输出
对于每组測试数据输出整形数列的最长递增子序列的长度,每一个输出占一行。
例子输入
7
1 9 10 5 11 2 13
2
2 -1
例子输出
5
1
来源

[521521]改编

这个题和前面做的那个单调递增子序列题目意思是一样的,可是这个题目数据量比較大,用前面的那种方法就会超时。前面的那一种方法dp[i]:用来储存以ai为末尾的最长递增子序列的长度。时间复杂度是o(n2),这个题目的数据范围到了100000,用这样的方法就会超时;

所以我们採用还有一种方法,用dp[i]:储存长度为i+1的递增序列中末尾元素的最小值;

建立一个一维数组dp[ ],用dp[i]保存长度为i的单调子序列的末尾元素的值,用top保存单调子序列的最大长度。

初始top=1,dp[1]=a1。

然后。我们从前向后遍历序列An(i : 2~n)。显然,我们会遇到两种情况:

1.a[i] > dp[top]。此时,我们把a[i]增加到长度为top的单调序列中,这时序列长度为top+1。top值也跟着更新,即dp[++top] = a[i]。

2.a[i]<=dp[top]。此时,a[i]不能增加长度为top的单调序列。那它应该增加长度为多少的序列呢?

做法是。从后向前遍历dp[ ] (j: top-1~1),直到满足条件 a[i] > dp[j],此时。类似于步骤1,我们能够把a[i]增加到长度为j的单调序列中。这时此序列长度为j+1;(这段话转载于http://www.cnblogs.com/mycapple/archive/2012/08/22/2651453.html

假设直接这样做的话。时间复杂度也会达到o(n2),可是这里还能够优化。我们在遍历更新的时候能够採用更高效率的方法。这里我们能够採用二分搜索,对前面的a[i]进行更新。这样的方法的时间复杂度就是o(nlogn)

以下是代码:

#include <cstdio>
#include <cstring>
const int maxn=100001;
int dp[maxn],a[maxn];
int Binary_search(int len,int k)//二分搜索
{//查找比第一个比dp[i]小或者是相等的位置
int start,end,mid;
start=1;
end=len;
while(start<=end)
{
mid=(start+end)>>1;
if(k==dp[mid])
return mid;
if(k>dp[mid])
start=mid+1;
else
end=mid-1;
}
return start;
}
int main()
{
int n,i,t,len;
while(scanf("%d",&n)!=EOF)
{
memset(dp,0,sizeof(dp));
for(i=0;i<n;i++)
scanf("%d",&a[i]);
len=1;
dp[1]=a[0];//这里要从1開始
for(i=1;i<n;i++)
{
t=Binary_search(len,a[i]);//通过二分搜索查找a[i]要插入的位置
dp[t]=a[i];//更新dp的值
if(t>len)//假设插入的位置在最后。更新最大的长度
len=t;
}
printf("%d\n",len);
}
}

以下是最优代码,好简短的:用了一个STL里面的lower_bound函数,这个函数就是二分查找。返回第一个比val小的位置,把这个函数使用熟练也会比較方便,与此相对的另一个upper_bound函数;http://blog.csdn.net/niushuai666/article/details/6734403 
这个内容能够參考这篇博客

#include<cstdio>
#include<algorithm>
using namespace std;
const int MAX=100100;
int num[MAX],top=0;
int main()
{
int n;
while(~scanf("%d",&n))
{
scanf("%d",&num[0]);
top=1;
for(int i=1;i!=n;i++)
{
scanf("%d",&num[i]);
int * p=lower_bound(num,num+top,num[i]);
if(p-num==top) ++top;
*p=num[i];
}
printf("%d\n",top);
} }





nyist oj 214 单调递增子序列(二) (动态规划经典)的更多相关文章

  1. ny214 单调递增子序列(二) 动态规划

    单调递增子序列(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 给定一整型数列{a1,a2...,an}(0<n<=100000),找出单调递增最长子序 ...

  2. nyoj 214 单调递增子序列(二)

    单调递增子序列(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 ,a2...,an}(0<n<=100000),找出单调递增最长子序列,并求出其长度. ...

  3. nyoj 214——单调递增子序列(二)——————【二分搜索加dp】

    单调递增子序列(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 给定一整型数列{a1,a2...,an}(0<n<=100000),找出单调递增最长 ...

  4. nyoj 214 单调递增子序列(二) 【另类dp】

    单调递增子序列(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描写叙述 ,a2...,an}(0<n<=100000),找出单调递增最长子序列.并求出其长度 ...

  5. nyoj 单调递增子序列(二)

    单调递增子序列(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 给定一整型数列{a1,a2...,an}(0<n<=100000),找出单调递增最长 ...

  6. nyoj_214_单调递增子序列(二)_201403182131

    单调递增子序列(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 给定一整型数列{a1,a2...,an}(0<n<=100000),找出单调递增最长 ...

  7. NYOJ-214 单调递增子序列(二) AC 分类: NYOJ 2014-01-31 08:06 233人阅读 评论(0) 收藏

    #include<stdio.h> #include<string.h> int len, n, i, j; int d[100005], a[100005]; int bin ...

  8. NYOJ-214 单调递增子序列(二) TLE 分类: NYOJ 2014-01-28 22:57 171人阅读 评论(0) 收藏

    #include<stdio.h> #include<stdlib.h> #define max(x,y) x>y?x:y #define MAXX 100005 int ...

  9. nyoj--214--单调递增子序列(二)(二分查找+LIS)

    单调递增子序列(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 给定一整型数列{a1,a2...,an}(0<n<=100000),找出单调递增最长子序 ...

随机推荐

  1. 触发器中的inserted表和deleted表

    触发器语句中使用了两种特殊的表:deleted 表和 inserted 表.Microsoft? SQL Server 2000 自动创建和管理这些表.可以使用这两个临时的驻留内存的表测试某些数据修改 ...

  2. Fedora下Eclipse/MyEclipse崩溃的解决方案

    Fedora19下使用myeclipse2013时,打开不到一分钟就异常关闭. 默认在home目录下生成一个log文件,里面显示的错误信息,说是libsoup.so文件导致出错.第一个想法是删除这个文 ...

  3. Oracle常用sql语句。

    最近工作中遇到了一些与oracle相关的问题,稍微整理一些工作中用到的SQL语句 时间相关 --查询距当前时间十分钟内的数据 select sysdate -interval '10' minute ...

  4. 黑马程序员_java基础笔记(02)...java语言基础组成

    ——————————  ASP.Net+Android+IOS开发..Net培训.期待与您交流!—————————— java语法(1:关键字,2:标识符,3:注释,4:常量和变量,5:运算符,6:语 ...

  5. 【Java】 用PriorityQueue实现最大最小堆

    PriorityQueue(优先队列),一个基于优先级堆的无界优先级队列. 实际上是一个堆(不指定Comparator时默认为最小堆),通过传入自定义的Comparator函数可以实现大顶堆. Pri ...

  6. 基于Laravel开发博客应用系列 —— 十分钟搭建博客系统

    1.创建文章数据表及其模型(0:00~2:30) 我们已经在上一节中为博客项目完成了大部分准备工作,现在首先要做的就是为这个项目创建一个新的文章表 posts及该表对应的模型类 Post,使用如下Ar ...

  7. react篇章-React Props

    state 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变.这就是为什么有些容器组件需要定义 state 来更新和修改数据. 而子组件只能通过 pro ...

  8. 【基本功】深入剖析Swift性能优化

    简介 2014年,苹果公司在WWDC上发布Swift这一新的编程语言.经过几年的发展,Swift已经成为iOS开发语言的“中流砥柱”,Swift提供了非常灵活的高级别特性,例如协议.闭包.泛型等,并且 ...

  9. VS15 openGL 编程指南 配置库 triangle例子

    最近去图书馆借了一本书<OpenGL编程指南(原书第八版)>,今天倒腾了一天才把第一个例子运行出来. 所以,给大家分享一下,希望能快速解决配置问题. 一.下载需要的库文件 首先,我们需要去 ...

  10. 批量ping工具fping

    批量ping工具fping   ping是各个系统自带的基于ICMP协议的主机探测工具.但该工具一次只能检测一个主机,不满足渗透测试批量探测的需要.Kali Linux提供一款批量探测工具fping. ...