此类问题一般常用的有两种算法,时间复杂度分别是O(n^2)和O(nlogn)

第一种,普通算法,用一个标记数组标记包括当前数的最长序列的长度,然后往前递归寻找,此类方法这里不多说了

文章的dp问题里已经用过多次了

下面着重介绍一下一种省时但是不常用的算法,整体思想是DP+二分搜索,用一个b[k]=m 来标记

k长度的最长序列下,最小的数是m,比如有一序列 5 3 7 4

首先b[1]=5,初始化长度为1的序列就是第一个数,接下来到3的时候,3独立的长度为1的序列小于5,所以b[1]=3,

那么b[2]=4 因为长度为2的序列有两个5-7,3-7,3-4,期中序列最大的数最小的就是4了

因此,寻找大于当前数的一个b[]可以用二分来查找

在这里再转载一篇文章来详解一下吧

View Code

1 /*
2 题目大意:求一条最长的上升子序列.题目解答:用一般的0(n^2)超时,只能采用0(nlogn).我们先来回顾一下poj 1887 Testing the CATCHER是怎么做的。
3 :首先我们确定了题目具有最优子结构,然后我们开始递归构造最优子结构,定义一个数组opt[i]表示前i个字符包含第i个字符的最长下降序列,
4 :然后又最优子结构递归出最优解公式:opt[i]=max(opt[j]+1),num[i] < num[j] && 0<=j<i<m。但是由于子结构的无序性,
5 :你只能遍历一遍寻出当中最大的可行解,导致复杂度一下子上升到n^2那我们再想问什么我们递归建立的子结构是不具有递增性或者说无序的呢,
6 :原因在于我们定义它的时候就确定了这个结果的产生(opt[i]前i个字符包含第i个字符的最长下降序列)要想要包含第i个字符那就不可能一定
7 :保证opt[i]>opt[i-1]。例如:2 5 4 1 opt[3]=2; opt[4]=1;那么我们怎么创建一个有序的最优子结构呢??要保证opt[i]>=opt[i-1]设opt[i]
8 :为前i个字符的最长子序列,这个显然不行,我们缺少子解得信息,无法更新,也就不能进行递归求解.那么求解一个n个字符的串,我们需要什么
9 :信息??1:第i个字符(这个属于源数据)。2:前i个字符的最长子序列 3:前i个字符的最长子序列的最优一个字符到底是多少?,如果有多个
10 :怎么办?先来看第三个条件的问题:如果有多个怎么办?例如 1 5 3 ....;前三个字符的最长子序列一看就知道是长度2,但是方案却又很多种
11 :{1,5}和{1,3}找那一种呢?当然是选取其中最小的一个,可以让目标增长的空间最大化3~无穷大>5~无穷大。好了现在三个条件都有了,关键的
12 :步骤来了,我们怎样存储2和3的两个条件opt[条件2]=[条件3]就是在前i个字符最长子序列.....(未完)
13
14 Source Code
15
16 Problem: 1631 User: wawadimu
17 Memory: 608K Time: 110MS
18 Language: C++ Result: Accepted
19
20 Source Code
21  */
22 #include<iostream>
23  using namespace std;
24
25  #define maxn 40010
26  int num[maxn];
27  int b[maxn];//b[k]=m ;长度为k的最长上升子序列中最小的数字值m
28 int opt[maxn];//opt[k]=l;前k个数字最长上升子序列的长度l
29 int p;//数组大小
30 int main()
31 {
32 //freopen("1631.txt","r",stdin);
33 int cas;
34 int i,j,k;
35 int l,r;
36 int blen;//保存当前b数组的大小(即已经求得的最长的上升子序列)
37 scanf("%d",&cas);
38 while(cas--)
39 {
40 scanf("%d",&p);
41 for(i=1;i<=p;i++)
42 scanf("%d",&num[i]);
43 b[1]=num[1];//只有一个数字是当然就是他本身
44 blen=1;//长度
45 for(i=1;i<=p;i++)//以此插入第i个数字
46 {
47 l=1; r=blen;
48 while(l<=r)//寻找一个刚刚大于num[i]的b[k]
49 {
50 int m=(l+r)>>1;
51 if(b[m] <num[i])
52 l=m+1;
53 else
54 r=m-1;
55 }
56 b[l]=num[i];//将大数字替换成小数字
57 opt[i]=l;//更新前i个数字的最长大小
58 blen = blen < l ? l : blen;//更新最长子序列长度
59 }
60 printf("%d\n",blen);//输出答案
61 }
62 return 1;
63 }

转载于:https://www.cnblogs.com/void/archive/2011/05/08/2040332.html

求最长XX序列的两种方法相关推荐

  1. c语言 | 求100-200之间的素数(两种方法)

    首先要求100-200之间的素数,要知道素数是什么? 素数就是质数,只能被自身和1整除 下面会介绍两种方法: 常规方法: 代码: int main() {     int i = 0;     for ...

  2. python求最大公约数和最小公倍数的两种方法

    最大公约数和最小公倍数的求解可以归结为求最大公约数,最小公倍数为两数乘积除以最大公约数 这里介绍两种求解方法,一种数常规易于理解的,一种是用辗转相除法实现的 # 求最大公倍数和最小公约数 a=int( ...

  3. C语言求最小公倍数和最大公约数的两种方法

    1.辗转相除法: 辗转相除法(又称欧几里得算法)是一种求最大公因数的方法,它的基本思想是:两个整数的最大公因数等于其中较小的数和两数相除的余数的最大公因数. #include <stdio.h& ...

  4. (C++)按照公式求圆周率pi的近似值的两种方法

    方法一 #include<cstdio> #include<cmath> //求圆周率pi的近似值int main(){double PI=0,mu=1;int i=1;whi ...

  5. 实现iOS长时间后台的两种方法:Audiosession和VOIP(转)

    分类: Iphone2013-01-24 14:03 986人阅读 评论(0) 收藏 举报 我们知道iOS开启后台任务后可以获得最多600秒的执行时间,而一些需要在后台下载或者与服务器保持连接的App ...

  6. Python中求1到20平方的两种方法

    #1.使用列表推导式 >>> [x**2 for x in range(1,21)] [1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, ...

  7. c语言中fact函数怎么调用,C语言程序题: 1、编写一个求n!的函数fact(n),要求fact函数分别用递归和非递归两种方法实现...

    点击查看C语言程序题: 1.编写一个求n!的函数fact(n),要求fact函数分别用递归和非递归两种方法实现具体信息 答:int fac(int n) //非递归{int f=1; for(;n;) ...

  8. 牛客 Tree(最小深度总和)(两种方法求重心)难度⭐⭐⭐

    题目链接 牛妹有一张连通图,由n个点和n-1条边构成,也就是说这是一棵树,牛妹可以任意选择一个点为根,根的深度deprootdep_{root}deproot​​为0,对于任意一个非根的点,我们将他到 ...

  9. c语言求出两个最大素数,求两个正整数的最大公约数      思路:这是一个很基本的问题,最常见的就是两种方法,辗转相除法和辗转相减法。通式分别为 f(x, y) = f(y, x%y...

    求两个正整数的最大公约数 思路:这是一个很基本的问题,最常见的就是两种方法,辗转相除法和辗转相减法.通式分别为 f(x, y) = f(y, x%y), f(x, y) = f(y, x - y) ( ...

最新文章

  1. 万万没想到 I 这 7 件超酷的事情,让开发更有效率
  2. Java注解(1)-注解基础
  3. ES5-6 作用域、作用域链、预编译、闭包基础
  4. L - Two Ants Gym - 102823L
  5. CF1406D:Three Sequences(贪心、构造)
  6. 深度优化LNMP之Nginx [2]
  7. 前端现在有发展前途吗?应届生好找工作吗?
  8. 酷炫的VR选座,阿里大麦背后的技术堪称豪华
  9. iShare.js分享插件
  10. 程序员也要学英语——限定词、形容词和副词
  11. java treemap指定排序_TreeMap按照key排序
  12. 默认暴露,分别暴露,整体暴露的再次学习及常用知识
  13. sdcc man阅读笔记(四)——存储类型关键字
  14. Chrome 字体模糊解决
  15. 小米2s Android pie,Android 9.0 Pie正式版发布,小米MIX 2S率先升级,国内第一款!
  16. 高性能低功耗服务器cpu,六核仅35W:AMD披露超低功耗服务器CPU
  17. MLAPI的升级之路
  18. 神通广大的WiFi劫持工具:Mana
  19. 河南2010年全国计算机技术与软件专业技术资格(水平)考试报名时间
  20. windows系统流氓软件太厉害卸载不掉怎么办?看我弄死它们

热门文章

  1. postgresql分页用法_postgresql分页数据重复问题的深入理解
  2. Python-Matplotlib可视化(6)——自定义坐标轴让统计图清晰易懂
  3. Python JSONPath示例
  4. linux命令 chmod_Linux chmod命令示例
  5. easymock_EasyMock注释– JUnit 4
  6. testng 监听器_TestNG侦听器
  7. python中获取文件大小_如何在Python中获取文件大小
  8. C++基础教程,基本的输入输出
  9. 开课吧Java课堂:如何创建多线程
  10. 阿里云成立技术脱贫联盟,要用技术助力脱贫