动态规划算法——最长上升子序列

今天我们要讲的是最长上升子序列(LIS)。
【题目描述】
给定N个数,求这N个数的最长上升子序列的长度。
【样例输入】      【样例输出】
7                     4
2 5 3 4 1 7 6

那么什么是最长上升子序列呢?
就是给你一个序列,请你在其中求出一段不断严格上升的部分,它不一定是要连续的。
就像这样:2,3,4,7和2,3,4,6就是序列2 5 3 4 1 7 6的两种选取方案,这个数列的最长长度是4.

那么,怎么求出它的最大上升子序列长度为4呢?这里介绍两种方法,都是以动态规划为基础的。


首先,我们先介绍较慢(O(n2))的方法。我们记num为到这个数为止时的最长上升子序列的长度。

 

这种方法就是每一次寻找“可以接下去的”,换句话说,设原序列为a,则
  当aj<ai(j<i)且numj+1>numi时,numi=numj+1。
对于每一个数,他都是在“可以接下去”的中,从前面的最优值+1转移而来。
因此,这个算法是可以求出正确答案的。

复杂度很明显,外层i枚举每个数,内层j枚举目前i的最优值,即O(n2)。

那么,有没有更快的方法呢?当然有。这回要用到二分
我们回想一下,在上面O(n2)的程序中,哪些地方看起来比较费时?
没错,就是内层用于更新i的循环。因为每一次它都要查找一遍,效率并不高。
回到题目,我们发现,他只要我们求长度,所以……?
我们可以模拟一个栈。
每遇到一个比栈顶元素大的数,就放进栈里,遇到比栈顶元素小的就二分查找前边的元素,找到一个“最应该被换掉的元素”,用新数去更新前边的元素。
这个算法不难证明也是正确的。因为前面每一次的枚举都换成了二分,内层的复杂度从n降到了log2,外层不变。所以总的复杂度是O(nlog2n)。

接下来,我先给出朴素算法的代码。

 1 #include<cstdio>
 2     const int MAX=1001;
 3     int a[MAX];
 4     int lis(int x)
 5     {
 6         int num[MAX];
 7         for(int i=0;i<x;i++)
 8         {
 9             num[i]=1;
10             for(int j=0;j<i;j++)
11             {
12                 if(a[j]<a[i]&&num[j]+1>num[i])
13                        num[i]=num[j]+1;
14             }
15         }
16         int maxx=0;
17         for(int i=0;i<x;i++)
18             if(maxx<num[i])
19                 maxx=num[i];
20         return maxx;
21     }
22     int main()
23     {
24         int n;
25         scanf("%d",&n);
26         for(int i=0;i<n;i++)
27             scanf("%d",&a[i]);
28         return !printf("%d\n",lis(n));
29     }

这个则是二分算法的代码:

 1 #include<cstdio>
 2 #include<algorithm>
 3 const int MAXN=200001;
 4     
 5 int a[MAXN];
 6 int d[MAXN];
 7     
 8 int main()
 9 {
10  int n;
11  scanf("%d",&n);
12  for(int i=1;i<=n;i++)
13      scanf("%d",&a[i]);
14  d[1]=a[1];
15  int len=1;
16  for(int i=2;i<=n;i++)
17  {
18    if(a[i]>d[len])
19      d[++len]=a[i];
20    else
21      {
22        int j=std::lower_bound(d+1,d+len+1,a[i])-d;
23        d[j]=a[i]; 
24      }
25  }
26  printf("%d\n",len);    
27  return 0;
28}

类似的,我们可以通过二分查找中改变“上确界”和“下确界”,以及符号(“<”和“<=”或“>”、“>=”等),求出最长不下降、不上升、严格下降子序列等问题。

 

由于作者也正在学习中,这篇文章只是借用别人的文章并加上自己的理解。

原文:http://www.cnblogs.com/frankchenfu/

转载于:https://www.cnblogs.com/zhengyongle506/p/10554208.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/394737.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何快速掌握一门新技术/语言/框架

IT行业中的企业特点是都属于知识密集型企业。这种企业的核心竞争力与员工的知识和技能密切相关。而如果你在企业中扮演的是工程师的角色的话&#xff0c;那么 你的核心竞争力就是IT相关的知识与技能的储备情况。而众所周知&#xff0c;IT行业是一个大量产生新知识的地方&#x…

c语言今天星期几问题,C语言输入今天星期几

满意答案迷茫03222015.07.24采纳率&#xff1a;55% 等级&#xff1a;9已帮助&#xff1a;665人123456789101112131415161718192021#include<stdio.h>int main(void){ enum weekday{ sun, mon, tue, wed, thu, fri, sat }; int n; printf("输入星期数(0-…

备忘录模式 详解

定义 在不破坏封装性的前提下&#xff0c;捕获一个对象的内部状态&#xff0c;并在该对象之外保存这个状态&#xff1b; 行为型模式 角色 发起人角色&#xff08;Originator&#xff09;&#xff1a;记录当前时刻的内部状态&#xff0c;负责定义哪些属于备份范围的状态&#xf…

dll oem证书导入工具_技术干货 | 恶意代码分析之反射型DLL注入

欢迎各位添加微信号&#xff1a;qinchang_198231 加入安全 交流群 和大佬们一起交流安全技术01技术概要这是一种允许攻击者从内存而非磁盘向指定进程注入DLL的技术&#xff0c;该技术比常规的DLL注入更为隐蔽&#xff0c;因为除了不需要磁盘上的实际DLL文件之外&#xff0c;它…

像程序员一样思考_如何像程序员一样思考-解决问题的经验教训

像程序员一样思考by Richard Reis理查德里斯(Richard Reis) 如何像程序员一样思考-解决问题的经验教训 (How to think like a programmer — lessons in problem solving) If you’re interested in programming, you may well have seen this quote before:如果您对编程感兴趣…

CF908G New Year and Original Order 数位DP

传送门 看到数据范围到\(10^{700}\)毫无疑问数位DP。那么我们最重要的问题是如何有效地维护所有数位排序之后的数的值。 对于某一个数\(x\)&#xff0c;设\(f_{x,i} (i \in [1,9])\)表示\(x\)中的所有数位的值\(\geq i\)的数位数量&#xff0c;比如说\(f_{6345982 , 7} 2 , f_…

锐捷亮相GITC:请互联网企业为我点个赞!

【51CTO.com原创稿件】GITC全球互联网技术大会已成功举办四届&#xff0c;今年的会议现场依然是摩肩接踵围观者众。围绕互联网热点技术&#xff0c;众人根据云、大数据、安全、运维、基础架构的不同主题&#xff0c;各自聚成小圈子展开深入交流。 锐捷的展位在主会场的内侧&…

c语言汇编混合编程方法,C语言和汇编语言混合编程方法

摘要&#xff1a; C语言是一种高级的面向过程的开发语言&#xff0c;汇编语言是一种低级的面向机器的编程语言。两者在程序设计开发方面各有优劣&#xff0c;目前两者的混合编程得到了广泛的应用。本文通过具体的实例&#xff0c;说明了混合编程的基本方法&#xff0c;为C语言应…

WPF Slider设置整数

IsSnapToTickEnabled"True" 转载于:https://www.cnblogs.com/Fred1987/p/6038608.html

api代理提取_了解提取API

api代理提取Interested in learning JavaScript? Get my ebook at jshandbook.com有兴趣学习JavaScript吗&#xff1f; 在jshandbook.com上获取我的电子书 Since IE5 was released in 1998, we’ve had the option to make asynchronous network calls in the browser using X…

react.lazy 路由懒加载_React lazy/Suspense使用及源码解析

React v16.6.0已经发布快一年了&#xff0c;为保障项目迭代发布&#xff0c;没有及时更新react版本&#xff0c;最近由于开启了新项目&#xff0c;于是使用新的react版本进行了项目开发。项目工程如何搭建&#xff0c;如何满足兼容性要求&#xff0c;如何规范化等等这里不作为介…

Dart编程语言入门

Dart基础入门语法介绍&#xff0c;详细说明可以查看相关视频《Dart编程语言入门》。 变量与常量 变量 1.使用 var 声明变量,默认值为 null var a;//null a 10;2.显示类型声明 int a;//null a 10;3.使用 var 声明&#xff0c;可赋予不同类型的值 var a; //null a 10; //int a…

《PHP精粹:编写高效PHP代码》——1.1节为什么要使用面向对象编程

本节书摘来自华章社区《PHP精粹&#xff1a;编写高效PHP代码》一书中的第1章&#xff0c;第1.1节为什么要使用面向对象编程&#xff0c;作者&#xff1a;&#xff08;美&#xff09;  Davey Shafik&#xff0c;更多章节内容可以访问云栖社区“华章社区”公众号查看 1.1 为什…

c语言数据结构系统化,C语言数据结构+数据库+操作系统

http://cv.qiaobutang.com/post/55c419b20cf2009bd4607795第二部分是专业相关的C &#xff0c;数据库&#xff0c;操作系统&#xff0c;数据结构。http://c.biancheng.net/cpp/u/shuju/数据(Data)是信息的载体&#xff0c;它能够被计算机识别、存储和加工处理。它是计算机程序加…

c语言判断一个序列是不是另一个的子序列

1 #include <stdio.h>2 #include <string.h>//添加字符串头文件3 4 int Subsequence(char s[], char t[]) 5 {6 int m,n,i,j;7 n strlen(s); //n表示序列S的长度8 m strlen(t); //m表示序列T的长度9 i0; 10 j0; 11 if (m>…

linux中python如何调用matlab的数据_特征锦囊:如何在Python中处理不平衡数据

今日锦囊特征锦囊&#xff1a;如何在Python中处理不平衡数据? Index1、到底什么是不平衡数据2、处理不平衡数据的理论方法3、Python里有什么包可以处理不平衡样本4、Python中具体如何处理失衡样本印象中很久之前有位朋友说要我写一篇如何处理不平衡数据的文章&#xff0c;整理…

源码安装zabbix遇到的报错集锦

报错1&#xff1a;checking for mysql_config... configure: error: MySQL library not found 解决办法&#xff1a;查找mysql_config #find / -name "mysql_config*" /usr/local/mysql/bin/mysql_config 在配置时将原有的 --with-mysql 改为 --with-mysql/usr/loca…

pso算法c++语言代码,一C++PSO(PSO)算法

收集和变化PSO算法&#xff0c;它可用于参考实施&#xff1a;#include #include #include #include #include #define rand_01 ((float)rand() / (float)RAND_MAX)const int numofdims 30;const int numofparticles 50;using namespace std;//typedef void (*FitnessFunc)(fl…

Hadoop不适合哪些场景 哪些场景适合?

Hadoop设计的目的主要包括下面几个方面&#xff0c;也就是所谓的适用场景&#xff1a; 1&#xff1a;超大文件 可以是几百M&#xff0c;几百T这个级别的文件。 2&#xff1a;流式数据访问 Hadoop适用于一次写入&#xff0c;多次读取的场景&#xff0c;也就是数据复制进去之后&a…

微服务 边界服务_遵循这些实用原则以获取精心设计的微服务边界

微服务 边界服务by Jake Lumetta杰克卢米塔(Jake Lumetta) 遵循这些实用原则以获取精心设计的微服务边界 (Follow these practical principles to get well-designed microservices boundaries) 如何避免使微服务太小和紧密耦合 (How to avoid making your microservices too …