最长上升子序列(LIS)长度的O(nlogn)算法 (动态规划)
转载来自http://blog.csdn.net/shuangde800/article/details/7474903
很详细啊
hdu 1950 Bridging signals
http://acm.hdu.edu.cn/showproblem.php?pid=1950
===================================
最长上升子序列(LIS)的典型变形,熟悉的n^2的动归会超时。LIS问题可以优化为nlogn的算法。
定义d[k]:长度为k的上升子序列的最末元素,若有多个长度为k的上升子序列,则记录最小的那个最末元素。
注意d中元素是单调递增的,下面要用到这个性质。
首先len = 1,d[1] = a[1],然后对a[i]:若a[i]>d[len],那么len++,d[len] = a[i];
否则,我们要从d[1]到d[len-1]中找到一个j,满足d[j-1]<a[i]<d[j],则根据D的定义,我们需要更新长度为j的上升子序列的最末元素(使之为最小的)即 d[j] = a[i];
最终答案就是len
利用d的单调性,在查找j的时候可以二分查找,从而时间复杂度为nlogn。
==================================
最长上升子序列nlogn算法
在川大oj上遇到一道题无法用n^2过于是,各种纠结,最后习得nlogn的算法
最长递增子序列,Longest Increasing Subsequence 下面我们简记为 LIS。
排序+LCS算法 以及 DP算法就忽略了,这两个太容易理解了。
首先,把d[1]有序地放到B里,令B[1] = 2,就是说当只有1一个数字2的时候,长度为1的LIS的最小末尾是2。这时Len=1
然后,把d[2]有序地放到B里,令B[1] = 1,就是说长度为1的LIS的最小末尾是1,d[1]=2已经没用了,很容易理解吧。这时Len=1
接着,d[3] = 5,d[3]>B[1],所以令B[1+1]=B[2]=d[3]=5,就是说长度为2的LIS的最小末尾是5,很容易理解吧。这时候B[1..2] = 1, 5,Len=2
继续,d[5] = 6,它在3后面,因为B[2] = 3, 而6在3后面,于是很容易可以推知B[3] = 6, 这时B[1..3] = 1, 3, 6,还是很容易理解吧? Len = 3 了噢。
第6个, d[6] = 4,你看它在3和6之间,于是我们就可以把6替换掉,得到B[3] = 4。B[1..3] = 1, 3, 4, Len继续等于3
第7个, d[7] = 8,它很大,比4大,嗯。于是B[4] = 8。Len变成4了
第8个, d[8] = 9,得到B[5] = 9,嗯。Len继续增大,到5了。
最后一个, d[9] = 7,它在B[3] = 4和B[4] = 8之间,所以我们知道,最新的B[4] =7,B[1..5] = 1, 3, 4, 7, 9,Len = 5。
- /*
- HDU 1950 Bridging signals
- -----最长上升子序列nlogn算法
- */
- #include<cstdio>
- #include<cstring>
- #define MAXN 40005
- int arr[MAXN],ans[MAXN],len;
- /*
- 二分查找。 注意,这个二分查找是求下界的; (什么是下界?详情见《算法入门经典》 P145)
- 即返回 >= 所查找对象的第一个位置(想想为什么)
- 也可以用STL的lowe_bound二分查找求的下界
- */
- int binary_search(int i){
- int left,right,mid;
- left=0,right=len;
- while(left<right){
- mid = left+(right-left)/2;
- if(ans[mid]>=arr[i]) right=mid;
- else left=mid+1;
- }
- return left;
- }
- int main()
- {
- freopen("input.txt","r",stdin);
- int T,p,i,j,k;
- scanf("%d",&T);
- while(T--){
- scanf("%d",&p);
- for(i=1; i<=p; ++i)
- scanf("%d",&arr[i]);
- ans[1] = arr[1];
- len=1;
- for(i=2; i<=p; ++i){
- if(arr[i]>ans[len])
- ans[++len]=arr[i];
- else{
- int pos=binary_search(i); // 如果用STL: pos=lower_bound(ans,ans+len,arr[i])-ans;
- ans[pos] = arr[i];
- }
- printf("%d\n",len);
- }
- return 0;
- }
最长上升子序列(LIS)长度的O(nlogn)算法 (动态规划)相关推荐
- 【训练题】航线设计 | 使用最长上升子序列(LIS)长度的O(nlogn)算法优化
[问题描述] 有一个国家被一条河划分为南北两部分,在南岸和北岸总共有N对城镇,每一城镇在对岸都有唯一的友好城镇.任何两个城镇都没有相同的友好城镇.每一对友好城镇都希望有一条航线来往.于是他们向政府提出 ...
- 最长上升子序列(LIS)长度
转自:http://www.slyar.com/blog/poj-2533-cpp.html POJ 2533 Longest Ordered Subsequence 属于简单的经典的DP,求最长上升 ...
- 最长上升子序列(LIS)长度及其数量
例题51Nod-1376,一个经典问题,给出一个序列问该序列的LIS以及LIS的数量. 这里我学习了两种解法,思路和代码都是参考这两位大佬的: https://www.cnblogs.com/reve ...
- 最长上升子序列(LIS) nlogn解法
文章目录 经典DP解法O(n^2) dp+二分法(O(nlogn)) 最长上升子序列LIS:Longest increasing subsequence 题目链接:Leetcode300. 最长递增子 ...
- 最长上升子序列(LIS)的求法
最长上升子序列(LIS) 给定一个长度为N的序列A 满足: 1. 1<=x1< x2< x3<-xk<=N 2. A[x1] < A[x2] < A[x3] ...
- 最长上升子序列 (LIS算法(nlong(n)))
设 A[t]表示序列中的第t个数,F[t]表示从1到t这一段中以t结尾的最长上升子序列的长度,初始时设F [t] = 0(t = 1, 2, ..., len(A)).则有动态规划方程:F[t] = ...
- 最长上升子序列LIS 动态规划 二分查找算法
所谓LIS表示最长上升子序列,是面试的时候非常容易考察的问题.对于一个序列h1,h2,...hN,其中的子序列hi1,hi2,...hik,满足hi1<hi2<...<hik,那么这 ...
- 耐心排序之最长递增子序列(LIS)
目录 一.问题引入 1.最长递增子序列(LIS) 2.问题分析 3.代码实现 4.问题思考 二.耐心排序 1.基本介绍 2.操作步骤 3.代码实现 三.俄罗斯套娃信封问题 1.题目描述 2.问题分析 ...
- 求数组中最长递增子序列的长度
题目:写一个时间复杂度尽可能低的程序,求一个一维数组(N个元素)中最长递增子序列的长度. 例:在序列[1, -1, 2, -3, 4, -5, 6, -7]中,其最长递增子序列的长度为4([1, 2, ...
- 最长递增子序列的长度(编程之美)
题目描述: 编程之美2.16中,求数组最长递增子序列的长度,例如数组为:1,-1,2,-3,4,-5,6,-7,那么最长递增序列是:1,2,4,6,长度是4. 可以看出,子序列不一定是连续的 解题思路 ...
最新文章
- c语言删除偶数号节点,第十二周作业
- php微服务架构设计模式,《微服务架构设计模式》读书笔记---第十一章:开发面向生产环境的微服务应用...
- 微信10个实用技巧,值得收藏!
- 查询指定目录下的文件中是否包含指定字符串
- 怎么把jad反编译放到Eclipse中
- Asp.Net MVC5入门学习系列⑥
- 电话聊天狂人 (25 分)(map映射 简单做法)
- s7200cpu224xp手册_西门子S7-200CPU224XP
- ACM的奇计淫巧_输入挂
- 126邮箱如何绑定qq邮箱服务器,ecshop使用企业邮箱、qq邮箱和126邮箱如何设置SMTP验证发送邮件...
- 电子计算机的基本概念简述
- 关注小升初 | 中考分数线刷屏的背后是数千东昌家长学生的泪水
- 图扑软件数字孪生汽车生产线,赋能智慧工厂科学运维
- 教程:简单十步,在 iTunes 申请 App Store 退款
- OpenCV批量读取路径下所有图片
- 基于高光谱影像的农作物检测应用简介
- 桥接模式和装饰者模式的区别
- android加固之后出问题,Android 应用加固
- Java BIO的基本介绍
- 小白Bert系列-生成pb模型,tfserving加载,flask进行预测
热门文章
- 分析器错误 分析器错误信息: 类型“Websystem.Global”不明确: 它可能来自程序集...的解决...
- 配置VS2008来Debug .Net框架源码
- 三元组顺序表表示的稀疏矩阵加法_知识表示学习记录(1)
- python皮卡丘编程代码_Python高级编程-(Part 6 部署代码)
- 征信考量社交化和大数据化
- CSS样式表初始化杂谈
- Mac Brew Uninstall MySql
- 学习Unix下C编程的实例
- Mysql连接的原理
- sqlserver中的循环遍历(普通循环和游标循环)(转载)