前言

先分享一篇文章《动态规划:从新手到专家》,作者正是通过这篇文章来学习的。文中对动态规划的设计思想做了非常详细的介绍,并通过简单问题和复杂问题对动态规划的设计流程进行剖析,以下是作者和出处:

  • 作者:Hawstein
  • 出处:http://hawstein.com/posts/dp-novice-to-advanced.html

问题描述

先介绍下问题,给定长度为N的整数序列:A[1], A[2], ......, A[N],求得其中最长非降子序列的长度,即LIS(longest increasing subsequence)。比如如下的整数序列:

5, 3, 4, 8, 6, 7

其最大非降子序列即为3, 4, 6, 7,长度为4。

动态规划求解

那么如何用动态规划来求解这个问题呢?动态规划中最重要的一部分就是定义状态转移方程,在这个问题中,如果我们定义d[i]为序列A[1], A[2], ..., A[i]的最长非降子序列,但很可惜,在后面思考中,我发现,d[i]和d[i-1]之间很难建立起状态转移关系,A[1]~A[i-1]和A[1]~A[i]二者的最长非降子序列间不一定有公共的部分,如1, 4, 2, 5, 3中前四个整数和前五个整数的最大非降子序列不一定有共同的部分,无法建立起状态转移关系。但如果用d[i]表示以元素A[i]结束的最长非降子序列的长度,那状态方程就有规律可循了,我们以上面的序列为例:

d(1) = max{1}; //只有5

d(2) = max{1}; //3之前没有比3小的

d(3) = max{1, d(2) + 1} = 2; //4之前有3

d(4) = max{1, d(2) + 1, d(3) + 1} = 3; //8之前有3, 4

d(5) = max{1, d(2) + 1, d(3) + 1} = 3; //6之前有3, 4

d(6) = max{1, d(2) + 1, d(3) + 1, d(5) + 1} = 4; //7之前有3, 4, 6

LIS = max(d[i]) = 4, 1 <= i < = 6

从上面的流程来看,先求出这个序列中以每个元素作为结尾的最大非降子序列的长度,那问题的解总是以序列中某个元素作为结尾的,所以取最大值即可。而且从上面的公式我们很容易看出求d[i]的过程,简单来说,就是从i往前找,如果某个元素A[j] < = A[i],那么以元素A[j]结尾的最长非降子序列再加上A[i]一定也是一个非降子序列,d[j] + 1肯定是一个非降子序列长度,找到所有符合条件的j,所有符合条件的d[j] + 1的最大值就一定是d[i]的值。从另一个角度去看,因为以A[i]为结尾的最长子序列的倒数第二个元素(假设长度不小于2)肯定是A[i]之前的某一个元素,所有A[j]作为倒数第二个元素的序列就是以A[i]为结尾的子序列。当然,还要考虑特殊的情况,假设A[i]之前没有比其更小的元素,则子序列就是其本身,长度为1。综上所述,状态转移方程如下:

d[i] = max(1, max(d[j] + 1)), 1 <= j < i, A[j] <= A[i];

最后问题的解即为:

LIS = max(d[i]); 1 <= i <= n, n为序列的长度

文章最后,贴上代码:

#include <iostream>
using namespace std;int LIS(int data[], int n)
{int *d = new int[n];int len = 1;for(int i = 0; i < n; i++){d[i] = 1;for(int j = 0; j < i; j++){if(data[j] <= data[i]){if(d[j] + 1 > d[i]){d[i] = d[j] + 1;}}}if(d[i]>len) len = d[i];}return len;
}int main()
{int data[] = {1, 2, 3, 4, 5, 0};cout << LIS(data, 6) << endl;return 0;
}

动态规划——最长非降子序列相关推荐

  1. 动态规划 dp02 最长非降子序列问题 c代码

    先看下题目: 给定一个由n个正整数组成的序列,从该序列中删除若干个整数,使剩下的整数组成非降子序列,求 最长的非降子序列. 例如,由12个正整数组成的序列为:48,16,45,47,52,46,36, ...

  2. 最长非降子序列(动态规划dp dynamic programming)

    首先要理解一下什么叫做非降子序列 非降子序列,简单来说就是指给出一个数字序列,在不改变整体顺序的情况下摘出几个来组成一个子序列,这个序列满足从小到大的排序顺序. 所以,最长非降子序列,不难理解就是从这 ...

  3. 最长非降子序列 动态规划 java

    1. 案例提出 给定一个由n个正整数组成的序列,从该序列中删除若干个整数,使剩下的整数组成非降子序列,求最长的非降子序列. 例如,由12个正整数组成的序列为: 48,16,45,47,52,46,36 ...

  4. 第1关:最长非降子序列(非连续)问题

    方法一:使用栈的方式 // // main.cpp // step1 // // Created by ljpc on 2018/12/8. // Copyright ? 2018年 ljpc. Al ...

  5. 面试题:求最长非重复子序列

    题目:求字符串的最长非重复子序列.比如字符串"dabaccdeff",它的最长非重复子序列为"dabcef" 这道题目与 面试题35:第一个只出现一次的字符 非 ...

  6. HDU2227(非降子序列的个数)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2227 题意:给定一个长度为n(n <= 100000)的整数序列,求其中的非降子序列的个数. 分析: ...

  7. 最长非下降子序列(O(nlogn))(offer收割)

    题目   如题 思路   核心思想是,维护一个数组ends,它记录了长度为k的子序列的末尾元素的最小值.听起来很抽象,我们不妨手动演示一遍整个过程.   假设数组a={2,9,4,27,29,15,7 ...

  8. 动态规划(3):最长非递减子序列

    题目 在一个数字序列中,找到一个最长的子序列(可以不连续),使得这个子序列是不下降(非 递减)的. 样例 输入 8 1 2 3 -9 3 9 0 11 输出 6 题解 最优子结构(举例):以3结尾的最 ...

  9. 动态数组怎么定义_动态规划最长回文子序列

    动态规划|最长回文子序列 今天一起来学习Leetcode第 516 题:最长回文子序列. 题目描述 题目分析 首先回文字符串指的是形如"a","aa",''ab ...

最新文章

  1. LabVIEW色彩定位实现药品包装质量检测(实战篇—4)
  2. Spring Cloud原理详解
  3. wireshark过滤使用
  4. K8S的SDN容器网络解决方案【机制篇】
  5. java实现行程长度编码,java 实现行程编码解码?
  6. LeetCode 524. Longest Word in Dictionary through Deleting
  7. Django 上传附件报The number of GET/POST parameters exceeded settings.DATA_UPLOAD_MAX_NUMBER_FIELDS错误
  8. 单片机c语言编程实训报告,单片机实训报告范文
  9. 汇编语言怎么编译python_汇编语言编译器的编写方法
  10. 冗余技术----线路冗余与生成树技术及其安全增强
  11. Excel 计算各种物料 平均采购价格
  12. 推荐一款强大的在线编译器
  13. UEFI Shell编程和使用
  14. 抓取网易云音乐网页歌单(url)js
  15. 区块链技术涉及哪些编程语言?
  16. 2022 年七大前沿科技:每一项都能改变世界
  17. 【c++】2020大一下c++期中考前小练习1
  18. 这几个消除笔软件,值得你们收藏
  19. c语言中常用数学符号,C语言中常用的数学公式
  20. 一张图分出你是用左脑还是右脑!

热门文章

  1. 2021完整版:Kubernetes Deployment故障排除的可视化指南
  2. 19 个接私活平台,有技术就有钱
  3. android 4.4 锁屏密码,安卓如何绕过锁屏密码:方法都在这儿了
  4. 如何下载Office365离线安装程序包并手动安装?
  5. SiTime 硅晶振与石英晶振的区别
  6. 英语句子成分分析(四)
  7. 简单归纳一下32位、64位、x86、x64的区别和联系
  8. 64位处理器_32位和64位的Windows 10和处理器(CPU)有什么区别
  9. web返回的数据集格式_200G倾斜数据无插件web端预览!兼容三端,有容乃大—MapGIS M3D数据格式...
  10. 21闭关修炼 解析分册