【南阳理工】 214
来源:互联网 发布:淘宝上买电视可靠吗 编辑:程序博客网 时间:2024/05/21 06:23
单调递增子序列(二)
- 描述
给定一整型数列{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型整数)! - 输出
- 对于每组测试数据输出整形数列的最长递增子序列的长度,每个输出占一行。
- 样例输入
71 9 10 5 11 2 1322 -1
- 样例输出
51
- 来源
[521521]改编 http://blog.csdn.net/whjkm/article/details/38610747
这个题和前面做的那个单调递增子序列题目意思是一样的,但是这个题目数据量比较大,用前面的那种方法就会超时,前面的那一种方法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)
下面是代码:
下面是最优代码,好简短的:用了一个STL里面的lower_bound函数,这个函数就是二分查找,返回第一个比val小的位置,把这个函数使用熟练也会比较方便,与此相对的还有一个upper_bound函数;http://blog.csdn.net/niushuai666/article/details/6734403 这个内容可以参考这篇博客
- 【南阳理工】 214
- 南阳理工:水仙花数
- 南阳理工:韩信点兵
- 南阳理工:成绩转换
- 南阳理工:众数问题
- 南阳理工:组合数
- 南阳理工:日期计算
- 南阳理工:整除个数
- 南阳理工:字母统计
- 南阳理工:小学生算术
- 南阳理工:笨小熊
- 南阳理工:开灯问题
- 南阳理工:交换输出
- 南阳理工:大小写互换
- 南阳理工:分数加减法
- 南阳理工:无线网络覆盖
- 南阳理工:九九乘法表
- 南阳理工:字符串替换
- 疯狂Activiti6.0连载(18) Activiti与Drools整合
- 判断什么时候使用输出流还是输出流
- 【Scikit-Learn 中文文档】多类和多标签算法
- ros常用命令
- Tcp、UDP协议详解
- 【南阳理工】 214
- 控制台打印异常,页面显示异常,http获取链接超时异常
- define与inline的区别
- 【Scikit-Learn 中文文档】集成方法
- Map集合day_16
- 一些想法(17.11.23)
- Android本地音乐播放器
- 为selenium配置webdriver
- 在JavaScript中typeof的用途介绍