引出:

问题描述:给出一个序列a1,a2,a3,a4,a5,a6,a7….an,求它的一个子序列(设为s1,s2,…sn),使得这个子序列满足这样的性质,s1<s2<s3<…<sn并且这个子序列的长度最长。输出这个最长的长度。(为了简化该类问题,我们将诸如最长下降子序列及最长不上升子序列等问题都看成同一个问题,其实仔细思考就会发现,这其实只是<符号定义上的问题,并不影响问题的实质)
例如有一个序列:1  7  3  5  9  4  8,它的最长上升子序列就是 1 3 4 8 长度为4.

分析:

这题目是经典的DP题目,也可叫作最长上升子序列或者 最长不下降子序列。有两种算法,复杂度分别为O(n*logn)和O(n^2) 。

算法1:
时间复杂度:O(n^2):
依次遍历整个序列,每一次求出从第一个数到当前这个数的最长上升子序列,直至遍历到最后一个数字为止,然后再取dp数组里最大的那个即为整个序列的最长上升子序列。我们用dp[i]来存放序列1-i的最长上升子序列的长度,那么dp[i]=max(dp[j])+1,(j∈[1, i-1]); 显然dp[1]=1,我们从i=2开始遍历后面的元素即可。

int dp[1000];
int LIS(int arr[1000], int n)
{for(int i=1; i<=n; ++i)dp[i] = 0;int ans;dp[1] = 1;for(int i=2; i<=n; ++i){ans = dp[i];for(int j=1; j<i; ++j){if(arr[i]>arr[j] && dp[j]>ans)ans = dp[j];}dp[i] = ans+1;}ans = 0;for(int i=1; i<=n; ++i){if(dp[i] > ans)ans = dp[i];}return ans;
}

算法2:
时间复杂度:(NlogN):
除了算法一的定义之外(p【i】相当于算法一中的arr【i】),增加一个数组b,b[i]用以表示长度为i最长子序列的最后一个数最小可以是多少。易证:i<j时,b[i]<b[j]。
在二分查找时,一直更新b[]内容,设此时b的总长度为k,
若1. arr[i] >= b[k], 则b[k+1] = arr[i];
若2. arr[i] <  b[k], 则在b[1..k]中用二分搜索大于arr[i]的最小值,返回其位置pos,然后更新b[pos]=arr[i]。

// num为要查找的数,k是范围上限
// 二分查找大于num的最小值,并返回其位置
int bSearch(int num, int k)
{  int low=1, high=k;  while(low<=high)  {  int mid=(low+high)/2;  if(num>=b[mid])  low=mid+1;  else   high=mid-1;  }  return low;
}  int LIS()
{int low = 1, high = n;int k = 1;b[1] = p[1];for(int i=2; i<=n; ++i){if(p[i]>=b[k])b[++k] = p[i];else{int pos = bSearch(p[i], k);b[pos] = p[i];}}return k;
}

以下是证明b[]的单调递增性:
b序列是严格递增的,即b[1] < b[2] < … < b[t]。
证明:
若b[i] >= b[i + 1],b[i + 1] 是长度为i+1的递增子序列的尾项的最小值,设此序列为x[1]..x[i+1],x[1]..x[i]即构成长度为i的递增子序列,x[i] < x[i+1] = b[i+1] <= b[i],与b[i]定义不符。

动态规划----最长子序列相关推荐

  1. 动态规划之-----单调递增最长子序列(nyoj17)

    单调递增最长子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 求一个字符串的最长递增子序列的长度 如:dabdbf最长递增子序列就是abdf,长度为4 输入 第一行 ...

  2. 动态规划:最长子序列问题

    关于动态规划中的最长子序列问题有很多优秀的解读,在这里推荐一位博主的关于最长子序列的文章,非常不错,配有大量的图片和文字解答,在这里推荐给大家.本文章转载自这里 1.基本概念 首先需要科普一下,最长公 ...

  3. 【算法】【递归与动态规划模块】两个字符串的公共最长子序列

    目录 前言 问题介绍 解决方案 代码编写 java语言版本 c语言版本 c++语言版本 思考感悟 写在最后 前言 当前所有算法都使用测试用例运行过,但是不保证100%的测试用例,如果存在问题务必联系批 ...

  4. 单调递增最长子序列(动态规划)

    7-1 单调递增最长子序列 (20分) 设计一个 O(n2)时间的算法,找出由n个数组成的序列的最长单调递增子序列. 输入格式: 输入有两行: 第一行:n,代表要输入的数列的个数 第二行:n个数,数字 ...

  5. LeetCode 1615. 最大网络秩 / 2389. 和有限的最长子序列 / 1626. 无矛盾的最佳球队(排序+动态规划)

    1615. 最大网络秩 2023.3.15 每日一题 题目描述 n 座城市和一些连接这些城市的道路 roads 共同组成一个基础设施网络.每个 roads[i] = [ai, bi] 都表示在城市 a ...

  6. 动态规划求一个序列的最长回文子序列(Longest Palindromic Substring )

    1.问题描述 给定一个字符串(序列),求该序列的最长的回文子序列. 2.分析 需要理解的几个概念: ---回文 ---子序列 ---子串 http://www.cnblogs.com/LCCRNblo ...

  7. 最长子序列DP和二分法

    输入一串数字例如: 5 6 8 1 3 4 9 输出最长递增子序列长度,示例中即 1 3 4 9或5 6 8 9 ,最大长度为4 public static void main(String[] ar ...

  8. 最长递增子序列问题 nyoj 17单调递增最长子序列 nyoj 79拦截导弹

    一,    最长递增子序列问题的描述 设L=<a1,a2,-,an>是n个不同的实数的序列,L的递增子序列是这样一个子序列Lin=<aK1,ak2,-,akm>,其中k1< ...

  9. 单调递增最长子序列 - 从最长公共子序列到单调递增最长子序列

    最长公共子序列 的 算法思路 在这里 点击进入  将 代码稍微改动一下 就可以   ,   最长公共子序列  是两个 字符串求 公共子序列  , 可以将其中的 一个 改为 从 a 到 z  这样输入另 ...

最新文章

  1. python运行不了control+shift+i_Python不支持 i ++ 语法的原因解析
  2. 防止被算力“锁死”,人工智能进化急需革命性算法
  3. [网站上线]Lamp环境及其后续配置
  4. 从尼古拉斯·泽卡斯开始学习
  5. Coursera课程Python for everyone:Quiz: REST, JSON, and APIs
  6. jQuery(function(){...})与(function($){...})(jQuery)的“兄弟”情结
  7. 钉钉轻松顶住信息洪流的原因,竟然是它
  8. linux nginx 代理iis,nginx 系列 linux下安装以及配置IIS分发
  9. jQuery.Event的一些用法
  10. 德勤发布2020技术趋势报告,五个新趋势可引发颠覆性变革
  11. 利用logminer恢复delete误删除操作的数据
  12. 谷歌浏览器安装过程 0911
  13. HTTP代理实现请求报文的拦截与篡改2--功能介绍+源码下载
  14. STL里面的sort()函数使用结构体
  15. 冷备份实验,裸设备上备份
  16. 翻译:谁将在AI中赚钱?by Simon Greenman
  17. python 颜色大全 颜色对应 matplotlab plot 颜色对应
  18. 树莓派无法打开摄像头模块,无法识别摄像头
  19. 【建议收藏】产品经理面试题合集
  20. 全栈式python工程师培训课程

热门文章

  1. 微博第三方登录 php,php 网站使用微博第三方授权登录
  2. 使用 patch 命令打补丁
  3. COLA 架构使用规范化
  4. 01-Empire-Lupin-One vulnhub靶场(ssh2john)
  5. kafka SASL认证介绍及自定义SASL PLAIN认证功能
  6. 惠普暗影精灵命令中心linux,暗影精灵2成功装上Sierra 12.5正式版
  7. 蓝牙路由器蓝牙点对多点组网蓝牙远程控制
  8. 自己使用的git总结
  9. error while loading shared libraries: libaio.so.1: cannot open shared object file: No such file
  10. 利用inotify+rsync实现linux文件批量更新