动态规划——最长非降子序列
前言
先分享一篇文章《动态规划:从新手到专家》,作者正是通过这篇文章来学习的。文中对动态规划的设计思想做了非常详细的介绍,并通过简单问题和复杂问题对动态规划的设计流程进行剖析,以下是作者和出处:
- 作者: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;
}
动态规划——最长非降子序列相关推荐
- 动态规划 dp02 最长非降子序列问题 c代码
先看下题目: 给定一个由n个正整数组成的序列,从该序列中删除若干个整数,使剩下的整数组成非降子序列,求 最长的非降子序列. 例如,由12个正整数组成的序列为:48,16,45,47,52,46,36, ...
- 最长非降子序列(动态规划dp dynamic programming)
首先要理解一下什么叫做非降子序列 非降子序列,简单来说就是指给出一个数字序列,在不改变整体顺序的情况下摘出几个来组成一个子序列,这个序列满足从小到大的排序顺序. 所以,最长非降子序列,不难理解就是从这 ...
- 最长非降子序列 动态规划 java
1. 案例提出 给定一个由n个正整数组成的序列,从该序列中删除若干个整数,使剩下的整数组成非降子序列,求最长的非降子序列. 例如,由12个正整数组成的序列为: 48,16,45,47,52,46,36 ...
- 第1关:最长非降子序列(非连续)问题
方法一:使用栈的方式 // // main.cpp // step1 // // Created by ljpc on 2018/12/8. // Copyright ? 2018年 ljpc. Al ...
- 面试题:求最长非重复子序列
题目:求字符串的最长非重复子序列.比如字符串"dabaccdeff",它的最长非重复子序列为"dabcef" 这道题目与 面试题35:第一个只出现一次的字符 非 ...
- HDU2227(非降子序列的个数)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2227 题意:给定一个长度为n(n <= 100000)的整数序列,求其中的非降子序列的个数. 分析: ...
- 最长非下降子序列(O(nlogn))(offer收割)
题目 如题 思路 核心思想是,维护一个数组ends,它记录了长度为k的子序列的末尾元素的最小值.听起来很抽象,我们不妨手动演示一遍整个过程. 假设数组a={2,9,4,27,29,15,7 ...
- 动态规划(3):最长非递减子序列
题目 在一个数字序列中,找到一个最长的子序列(可以不连续),使得这个子序列是不下降(非 递减)的. 样例 输入 8 1 2 3 -9 3 9 0 11 输出 6 题解 最优子结构(举例):以3结尾的最 ...
- 动态数组怎么定义_动态规划最长回文子序列
动态规划|最长回文子序列 今天一起来学习Leetcode第 516 题:最长回文子序列. 题目描述 题目分析 首先回文字符串指的是形如"a","aa",''ab ...
最新文章
- LabVIEW色彩定位实现药品包装质量检测(实战篇—4)
- Spring Cloud原理详解
- wireshark过滤使用
- K8S的SDN容器网络解决方案【机制篇】
- java实现行程长度编码,java 实现行程编码解码?
- LeetCode 524. Longest Word in Dictionary through Deleting
- Django 上传附件报The number of GET/POST parameters exceeded settings.DATA_UPLOAD_MAX_NUMBER_FIELDS错误
- 单片机c语言编程实训报告,单片机实训报告范文
- 汇编语言怎么编译python_汇编语言编译器的编写方法
- 冗余技术----线路冗余与生成树技术及其安全增强
- Excel 计算各种物料 平均采购价格
- 推荐一款强大的在线编译器
- UEFI Shell编程和使用
- 抓取网易云音乐网页歌单(url)js
- 区块链技术涉及哪些编程语言?
- 2022 年七大前沿科技:每一项都能改变世界
- 【c++】2020大一下c++期中考前小练习1
- 这几个消除笔软件,值得你们收藏
- c语言中常用数学符号,C语言中常用的数学公式
- 一张图分出你是用左脑还是右脑!
热门文章
- 2021完整版:Kubernetes Deployment故障排除的可视化指南
- 19 个接私活平台,有技术就有钱
- android 4.4 锁屏密码,安卓如何绕过锁屏密码:方法都在这儿了
- 如何下载Office365离线安装程序包并手动安装?
- SiTime 硅晶振与石英晶振的区别
- 英语句子成分分析(四)
- 简单归纳一下32位、64位、x86、x64的区别和联系
- 64位处理器_32位和64位的Windows 10和处理器(CPU)有什么区别
- web返回的数据集格式_200G倾斜数据无插件web端预览!兼容三端,有容乃大—MapGIS M3D数据格式...
- 21闭关修炼 解析分册