最长不下降子序列的O(n^2)算法和O(nlogn)算法
一、简单的O(n^2)的算法
很容易想到用动态规划做。设lis[]用于保存第1~i元素元素中最长不下降序列的长度,则lis[i]=max(lis[j])+1,且num[i]>num[j],i>j。然后在lis[]中找到最大的一个值,时间复杂度是O(n^2)。
代码实现:
int Longest_Increasing(int num[],int n){
int lis[n],i,j;
for(i=0;i<n;i++){
lis[i]=1;
for(j=0;j<i;j++)
if(num[i]>num[j]&&lis[j]+1>lis[i])
lis[i]=lis[j]+1;
}
int maxn=0;
for(i=0;i<n;i++) if(maxn<lis[i]) maxn=lis[i];
return maxn;
}
二、复杂点的O(nlogn)算法
概述:O(nlogn)的算法关键是它建立了一个数组b[],b[i]表示长度为i的不下降序列中结尾元素的最小值,用K表示数组目前的长度,算法完成后K的值即为最长不下降子序列的长度。
具体点来讲:
设当前的以求出的长度为K,则判断a[i]和b[k]:
1.如果a[i]>=b[k],即a[i]大于长度为K的序列中的最后一个元素,这样就可以使序列的长度增加1,即K=K+1,然后现在的b[k]=a[i];
2.如果a[i]<b[k],那么就在b[1]...b[k]中找到最大的j,使得b[j]<a[i],然后因为b[j]<a[i],所以a[i]大于长度为j的序列的最后一个元素,那么就可以更新长度为j+1的序列的最后一个元素,即b[j+1]=a[i]。
算法复杂度的分析:
因为共有n个元素要进行计算;每次计算又要查找n次,所以复杂度是O(n^2),但是,注意到b[]数组里的元素的单调递增的,所以我们可以用二分法,查找变成了logn次。这样算法的复杂度就变成了O(nlogn)。具体算法实现请看代码(7-13update:以前的blog用不了了,所以重新弄过了)。
下面这段代码解决的是一道OI的题。
http://www.rqnoj.cn/Problem_Show.asp?PID=167
#include<iostream>
using namespace std;
long f[100001]={0},l=1,r,m,t=0,a;
inline void BinarySearch(){
while(l<=r){
m=(l+r)>>1;
if(f[m]==a){l=m;return;}
else
if(f[m]>a)l=m+1;
else r=m-1;
}
}
main(){
long n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a;
if(a==0)continue;
l=1,r=t;
BinarySearch();
if(l<=t)f[l]=a;
else t++,f[t]=a;
}
cout<<t;
}
最长不下降子序列的O(n^2)算法和O(nlogn)算法的更多相关文章
- 最长不下降子序列(LIS)
最长上升子序列.最长不下降子序列,解法差不多,就一点等于不等于的差别,我这里说最长不下降子序列的. 有两种解法. 一种是DP,很容易想到,就这样: REP(i,n) { f[i]=; FOR(j,,i ...
- 最长不下降子序列 O(nlogn) || 记忆化搜索
#include<stdio.h> ] , temp[] ; int n , top ; int binary_search (int x) { ; int last = top ; in ...
- tyvj 1049 最长不下降子序列 n^2/nlogn
P1049 最长不下降子序列 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 求最长不下降子序列的长度 输入格式 第一行为n,表示n个数第二行n个数 输出格式 ...
- 最长不下降子序列//序列dp
最长不下降子序列 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 求最长不下降子序列的长度 输入格式 第一行为n,表示n个数第二行n个数 输出格式 最长不下降 ...
- 【tyvj】P1049 最长不下降子序列
时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 求最长不下降子序列的长度 输入格式 第一行为n,表示n个数 第二行n个数 输出格式 最长不下降子序列的长度 测 ...
- hdu 4604 Deque(最长不下降子序列)
从后向前对已搜点做两遍LIS(最长不下降子序列),分别求出已搜点的最长递增.递减子序列长度.这样一直搜到第一个点,就得到了整个序列的最长递增.递减子序列的长度,即最长递减子序列在前,最长递增子序列在后 ...
- 最长不下降子序列nlogn算法详解
今天花了很长时间终于弄懂了这个算法……毕竟找一个好的讲解真的太难了,所以励志我要自己写一个好的讲解QAQ 这篇文章是在懂了这个问题n^2解决方案的基础上学习. 解决的问题:给定一个序列,求最长不下降子 ...
- SPOJ 4053 - Card Sorting 最长不下降子序列
我们的男主现在手中有n*c张牌,其中有c(<=4)种颜色,每种颜色有n(<=100)张,现在他要排序,首先把相同的颜色的牌放在一起,颜色相同的按照序号从小到大排序.现在他想要让牌的移动次数 ...
- SPOJ 3943 - Nested Dolls 最长不下降子序列LIS(二分写法)
现在n(<=20000)个俄罗斯套娃,每个都有宽度wi和高度hi(均小于10000),要求w1<w2并且h1<h2的时候才可以合并,问最少能剩几个. [LIS]乍一看跟[这题]类似, ...
随机推荐
- web安全测试-AppScan使用分享
这里主要分享如何使用AppScan对一大项目的部分功能进行安全扫描. ----------------------------------------------------------------- ...
- 未能加载文件或程序集“DeveloperKit10.1/DotNet/ESRI.ArcGIS.ADF.Local.或它的某一个依赖项
使用VS2010进行ArcGIS Engine 10.1进行开发过程中,出现: 错误 1 未能加载文件或程序集“file:///D:/ArcGIS/DeveloperKit10.0/DotNet/ES ...
- git——学习笔记(三)分支管理
一.创建.合并分支 每次提交,git都往后走一格,串成一跳时间线,head指向的是分支,分支指向提交.master是主分支,dev是另一条分支,分支就像指针一样,合并.删除分支时,修改的都是指针,工作 ...
- Eclipse中一些快捷键
用到哪里更新到哪里~~~ 1,代码自动对齐 ctrl+shift+f 2,自动填充相关的包 alt+/ 注意选择好需要的包 3,注释某几行代码 选定后ctrl+/ 4,设置自动补全 最简单的修改方 ...
- 2016 - 1- 22 NSURLConnetction --- POST请求
一:与上一篇博客中的GET方法类似 只不过需要多注意,如果要改变请求的类型,需要生成NSMutableURLRequest对象才可以设置请求的类型. NSURL *url = [NSURL URLW ...
- 使用httputils上传图片到服务器
//创建httpUtils对象 HttpUtils mRegHttpUtils = new HttpUtils(); //图片路径 String path = "/sdcard/Downlo ...
- Euro Efficiency_完全背包
Description On January 1st 2002, The Netherlands, and several other European countries abandoned the ...
- 内存回收,Dispose,Close,Finalie(C#中的析构函数)
NET中的资源分托管和非托管,所谓的托管是指CLR(通用语言运行时)中进行管理的资源,它可以由CLR自动进行内存回收. 也就是大家熟知的GC(垃圾回收机制). 而对于 非托管资源,比如数据库连接,CO ...
- 用NSOperation和NSOperationQueue实现多线程编程
1.上一讲简单介绍了NSThread的使用,虽然也可以实现多线程编程,但是需要我们去管理线程的生命周期,还要考虑线程同步.加锁问题,造成一些性能上的开销.我们也可以配合使用NSOperation和NS ...
- matlab 不要图像界面
参考文献matlab -nodesktop