最长非降子序列 动态规划 java
1. 案例提出
给定一个由n个正整数组成的序列,从该序列中删除若干个整数,使剩下的整数组成非降子序列,求最长的非降子序列。
例如,由12个正整数组成的序列为:
48,16,45,47,52,46,36,28,46,69,14,42
请在序列中删除若干项,使剩下的项为非降(即后面的项不小于后面的项)序列,剩下的非降序列最长为多少项?
2.递推实现动态规划设计
设序列的各项为a[1],a[2],…,a[n](可随机产生,也可从键盘依次输入),对每一个整数操作为一个阶段,共为n个阶段。
(1)建立递推关系
设置b数组,b[i]表示序列的第i个数(保留第i个数)到第n个数中的最长非降子序列的长度,i=1,2,…,n。对所有的j>i,比较当a[j]≥a[i]时的b[j]的最大值,显然b[i]为这一最大值加1,表示加上a[i]本身这一项。
因而有递推关系:
b[i]=max(b[j])+1 (a[j]≥a[i],1≤i<j≤n)
边界条件:b[n]=1
(2)逆推计算最优值
b[n]=1;
for(i=n−1;i>=1;i−−)
{max=0;for(j=i+1;j<=n;j++)
if(a[i]<=a[j]&& b[j]>max)
max=b[j];
b[i]=max+1; // 逆推得b[i]
}
逆推依次求得b[n−1],…,b[1],比较这n−1个值得其中的最大值lmax,即为所求的最长非降子序列的长度即最优值。
(3)构造最优解
从序列的第1项开始,依次输出b[i]分别等于lmax,lmax−1,…,1的项a[i],这就是所求的一个最长非降子序列。
3. 递归实现动态规划设计
(1)建立递归关系
设q(i)表示序列的第i个数(保留第i个数)到第n个数中的最长非降子序列的长度,i=1,2,…,n。对所有的j>i,比较当a[j]≥a[i]时的q(j)的最大值,显然q(i)为这一最大值加1,表示加上a[i]本身这一项。
因而有递归关系:
q(i)=max(q(j))+1 (a[j]≥a[i],1≤i<j≤n)
递归出口:q(n)=1
(2)递归函数设计
int q(int i)
{int j,f,max;
if(i==n)f=1;
else
{ max=0;
for(j=i+1;j<=n;j++)
if(a[i]<=a[j]&& q(j)>max)
max=q(j);
f=max+1;
}
returnf;
}
(3) 在主函数中依次调用q(n−1),…,q(1),比较这n−1个值得其中的最大值lmax,即为所求的最长非降子序列的长度即最优值。
(4)构造最优解
从序列的第1项开始,依次输出q(i)分别等于lmax,lmax−1,…,1所那就的项a[i],这就是所求的一个最长非降子序列。
(5)递归实现动态规划程序设计
// 递归实现动态规划
package basic_practice;import java.util.Scanner;public class anlian_bfs {static int a[]=new int[20];//默认值为0static int n;static int q(int i){//第i个数字到第n个数字的最长非降数字个数int j,f,max;if(i==n)f=1; //递归出口,如果是第n个数,则为1else {max=0;for(j=i+1;j<n;j++){if(a[j]>a[i]&&q(j)>max){//因为a[i]比a[j]小,所以a[i]就可以加入a[j]到a[n]构成的非降序列,长度加一max=q(j);}}f=max+1;//长度加一}return f;}public static void main(String[] args) {Scanner in=new Scanner(System.in);n=in.nextInt();for(int i=0;i<n;i++)a[i]=in.nextInt();int lmax=0;for(int i=n-1;i>=1;i--) if(q(i)>lmax) lmax=q(i); //逐个比较求最大System.out.println(lmax);//System.out.println(q(1));int x=lmax;for(int i=1;i<=n;i++)if(q(i)==x){System.out.print(a[i]+" ");//每个非降序列的第一个元素x--;} }
}
4.程序运行示例与讨论
运行程序
12
48 16 45 47 52 46 36 28 46 69 14 42
输出:
5.
16 45 47 52 69
注意,所给序列长度为5的非降子序列可能有多个,这里只输出其中一个。
由上可知,在动态规划设计中,最优值可经递推得到,也可经递归得到。一般地,应用递推效率更高些,以下各案例的动态规划设计中均应用递推得最优值。
最长非降子序列 动态规划 java相关推荐
- 最长非降子序列(动态规划dp dynamic programming)
首先要理解一下什么叫做非降子序列 非降子序列,简单来说就是指给出一个数字序列,在不改变整体顺序的情况下摘出几个来组成一个子序列,这个序列满足从小到大的排序顺序. 所以,最长非降子序列,不难理解就是从这 ...
- 动态规划 dp02 最长非降子序列问题 c代码
先看下题目: 给定一个由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 ...
- 最长单调递增子序列 动态规划 (java)
题目描述: 设计一个O(N^2)算法,找出n个数据组成的序列的最长单调递增子序列. 输入示例: 8 1 2 3 -9 3 9 0 11 输出示例: 5 1 2 3 9 11 设计思路: 有一个数组 a ...
- 动态规划(3):最长非递减子序列
题目 在一个数字序列中,找到一个最长的子序列(可以不连续),使得这个子序列是不下降(非 递减)的. 样例 输入 8 1 2 3 -9 3 9 0 11 输出 6 题解 最优子结构(举例):以3结尾的最 ...
最新文章
- 有汇编功能的python编译器_7.12 计算机基础理念与python解释器编译器安装使用
- 虚拟机创建静默快照报错:msg.snapshot.error-QUIESCINGERROR
- 安装sql2012 需要安装net3.5 没有的话 安装不成功
- 【SPOJ - QTREE2】Query on a tree II(LCA,倍增)
- linux 解压tar.jz,linux系统压缩文件和解压缩命令
- 面试了上百位性能测试后,我发现了一个令人不安的事实
- Python笔记之读取yaml文件
- python安装sqlalchemy-Python流行ORM框架sqlalchemy安装与使用教程
- 玩机:解决小米手机锁屏忘记密码无法解锁
- python优化网站_小旋风网站优化 - 致力于Python高品质站群系统的产品研发
- 边城工具集:绘图及标注工具
- 用html制作奥运五环图案,用 canvas 制作奥运五环
- 新手需要知道decode 和 encode 区别【转载】
- 从零开始 CMake 学习笔记 (G)compile-flags
- clamav的unrar解压模块加载
- JS 按钮下一步 下拉菜单内容转换
- Flask框架四:模板继承以及豆瓣案例
- 如何在html 中添加ppt文件,如何在ppt中插入网页
- 计算机主板的安装过程,电脑主板安装四大步骤全程讲解
- 【深度学习基础知识 - 28】三维重建中的点云、体素、mesh