题目描述

设计一个算法,找出由n个数组成的序列的最长单调递增子序列并对算法进行分析。要求时间复杂度分别为O(nlogn)和O(n^2).

方法1

对数组进行遍历,我们设置一个计数器来统计递增序列的长度并初始化为1(最短的递增序列是一个单独的数组,因此初始化为1)每次如果后一个数>前一个数,则计数器+1,否则将计数器置为1。当每次碰到递减的数时,更新最大计数器,然后再将计数器置为1.

代码:

#include <iostream>
#include <vector>
#include <cstdio>
using namespace std;
int main()
{//数组的长度int n;cin>>n;//数组元素int number;vector<int>arr;for(int i = 0;i < n;i++){cin>>number;arr.push_back(number);}count = 1;max_count = 0;for(int i = 1;i < n;i++){if(arr[i] < arr[i-1]){max_count = max(max_count,count);count = 1}elsecount += 1;}cout<<max_count;return 0;

方法1算法分析

方法1我们只需要遍历我们的数组,找到一个递增序列就+1即可,这是一次遍历,所以时间复杂度为O(n)

方法2

利用动态规划解决问题。我们发现其实截止到数组arr[i]的最长单调子序列长度其实就是之前的元素的最大子序列长度.我们不断更新当前元素之前的最大单调子序列长度,只是为了更新我们当前元素的最大长度。
所以我们设置b[0:n-1]来存储数组中a[i]的最大单调递增子序列长度,我们要做的就是不断更新b中的元素。

#include <iostream>
using namespace std;
const int maxn=100010;
int a[maxn]={0},b[maxn]={0};
int LIS(int a[],int n)
{int k;b[0]=1;for(int i=1;i<n;i++){k=0;for(int j=0;j<i;j++){if(a[j]<=a[i]&&k<b[j])//找到比a[i]小的数,取比a[i]小的数集合中的最大值更新k=b[j];}b[i]=k+1;}int res=0;for(int i=0;i<n;i++){res=res<b[i]?b[i]:res;}return res;
}
int main()
{int n;cin>>n;for(int i=0;i<n;i++){scanf("%d",&a[i]);//这里天坑!不用scanf和printf会超时       }cout<<printf("%d",LIS(a,n))return 0;
}

方法2算法分析

我们每次在找a[i]的最大递增序列时都会遍历之前的所有b[0:i],因此算法时间复杂度为O(n^2)

方法3

方法3是一种最为简便的方法,扩展序列。
我们发现在遍历到i的时候,前面所有b数组中的元素我们都需要遍历,因此这造成了很大程度的时间浪费。我们可以重新定义一个数组B,数组B[k]中存储的是长度为k的递增序列中最小元素末尾。所以当我们遍历到a[i]时需要比较:
· a[i]>=B[k],B[k++] = a[i]
· a[i]<B[k],我们在B数组中进行二分查找,因为数组B有序,我们查找到一个B[j-1]<=a[i]<B[j]的位置,将B[j]更新为a[i]

#include <iostream>
using namespace std;
const int maxnum = 100010;
int a[maxnum] = {0};
int b[maxnum] = {0};
int binarysearch(int x,int i ,int j)
{int l = i,r = j;while(l <= r){mid = (l+r)//2;if(x==b[mid])return mid;else if(x<b[mid])r=mid-1;elsel=mid+1;}return l;
}
int LIS(int a[],int n)
{int k = 1;b[1] = a[0];for(int i = 1;i < n;i++){if(a[i]>=b[k])b[++k]=a[i];elseb[binarysearch(a[i],1,k)]=a[i];}return k;
}
int main()
{int n;cin>>n;for(int i = 0;i < n;i++)cin>>a[i];cout<<LIS(a,n)<<endl;return 0;

方法3算法分析

b[k]为长度为k的递增序列的末尾最小元素,当碰到一个小于当前a[i]的数字,我们会进入b中进行位置搜索,搜到了位置j后我们会立刻用a[i]这个较小的元素更新b[j],因为原位置b[j]是大于a[i]的,所以我们要更新成更小的。算法时间复杂度为O(nlogn)

算法分析——单调递增子序列相关推荐

  1. NYOJ 单调递增子序列(二)

    单调递增子序列(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 给定一整型数列{a1,a2...,an}(0<n<=100000),找出单调递增最长子序 ...

  2. NYOJ 214 单调递增子序列(二)

    单调递增子序列(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 给定一整型数列{a1,a2...,an}(0<n<=100000),找出单调递增最长子序 ...

  3. 最长单调递增子序列 [转]

    [转] http://skynewborn.blog.sohu.com/66594610.html 单调子序列包含有单调递增子序列和递减子序列,不失一般性,这里只讨论单调递增子序列.首先,从定义上明确 ...

  4. 最长单调递增子序列O(NlogN)算法

     O(NlgN)算法 假设存在一个序列d[1..9] ={ 2,1 ,5 ,3 ,6,4, 8 ,9, 7},可以看出来它的LIS长度为5.  下面一步一步试着找出它.  我们定义一个序列B,然后 ...

  5. 最长单调递增子序列 python_最长单调递增子序列

    前面三篇博客分别讲了贪心,递归,分治,今天就说个简单的动态规划(DP)的题目吧.在我心中DP算是比较难的算法,尤其像状态DP,树形DP,因为实力问题就说一个简单的线性DP--最长单调递增子序列. 题目 ...

  6. java最长单调递增子序列_最长单调递增子序列问题

    最长单调递增子序列问题 题目:设计一个 O( n ^ 2 )复杂度的算法,找出由 n 个数组成的序列的最长单调递增子序列. import java.util.Scanner; public class ...

  7. 输出最长单调递增子序列java_动态规划实现最长单调递增子序列

    1. 实验环境 操作系统:Mac 64 运行内存:16GB 编程语言:Java 编译环境:Eclipse 2. 题目要求 设计一个Ο(nlgn)时间的算法,求一个 n 个数的序列的最长单调递增子序列. ...

  8. 算法实验-最长单调递增子序列长度

    问题描述 解决思路 O(n^2) 首先考虑使用动态规划的方法解决该问题.首先将原问题分解为子问题.对于长度为n的序列(从下标1开始),假设前n-1个元素形成了n-1个以arr[i]结尾的单调递增最长子 ...

  9. 动态规划作业 最长单调递增子序列

    动态规划作业 1.最长单调递增子序列 设计一个 O(n2)时间的算法,找出由 n 个数组成的序列 a 的最长单调递增子序列. 提示: 用数组 b[0:n]纪录以 a[i] (0<= i< ...

最新文章

  1. Codemirror-开源在线代码编辑器
  2. php扇形分布图,PHP制作3D扇形统计图以及对图片进行缩放操作实例
  3. 对C语言 结构指针变量做函数的参数 结构作为函数的参数
  4. 按home退出程序到后台后再打开崩溃的问题
  5. pandas的基本使用
  6. 轻松搞定对容器实例日志设置定期清理和回卷
  7. 数据库原理 知识点总结
  8. 《乌合之众》读书笔记(part2)--打动群体心灵的,是传奇中的英雄,而绝非现实中的英雄本身
  9. 商汤3DAR团队-3D视觉组招聘
  10. infor wms 中英文对照_为什么要wms?_wms吧
  11. POJ 1451 T9 (字典树好题)
  12. Tomcat服务安全加固和优化
  13. zabbix详解(一)——zabbix基本概念
  14. lzg_ad:XPE中EWF组件
  15. SHL笔试全攻略(转)
  16. Macbook Pro 安装 win10 单操作系统
  17. Linux操作系统加固
  18. 原创分享 计算机毕业设计PySpark+LSTM+Hadoop招聘推荐系统 招聘大数据 招聘数据分析 协同过滤算法(基于物品+基于用户) 招聘可视化大屏 就业推荐系统 就业数据分析
  19. Android网上购物商城测试,Android 应用上架小米商城Monkey 测试不通过
  20. 实例:泰坦尼克号幸存者的预测

热门文章

  1. 2022-2028全球与中国四侧引脚扁平封装市场现状及未来发展趋势
  2. 项目实战:Qt给指定手机发送短信(点对点、群发等等)
  3. C语言实验(四):循环(输出100到200之间的素数、计算房贷等)
  4. 从2891个专栏里找出来的宝贝,望珍惜
  5. 许可证服务器读取文件时警告错误,在尝试获取许可证时出现无法从许可证服器上读取数据的错误信息...
  6. 轴系扭转振动仿真(SIMULINK)
  7. 电压越低采集的ad值反而变大_网络课堂 | 专业基础知识培训系列3采集仪功能说明与选择...
  8. 超长干货!Cocos Creator 粒子系统详解,零代码实现逼真自然效果
  9. jQuery+flex(简单实用)简单实现淘宝京东五星好评(附注释)
  10. Qt 静态编译(5.15.2 MinGW 32-bit)