动态规划最长上升子序列问题讲解和【题解】——最长上升子序列

news/2024/10/5 1:50:52 标签: c++, 动态规划, 最长上升子序列LIS, 算法

动态规划最长上升子序列讲解和题解——最长上升子序列

  • 最长上升子序列问题讲解
    • 1.概念解析
    • 2.举例了解
    • 3.示例程序
  • 最长上升子序列
    • 题目描述
    • 输入格式
    • 输出格式
    • 输入输出样例
      • 输入 #1
      • 输出 #1
    • 提示
    • 思路解析

最长上升子序列问题讲解

1.概念解析

    最长上升子序列 ( L o n g e s t   I n c r e a s i n g   S u b s e q u e n c e , L I S ) (Longest\space Increasing\space Subsequence,LIS) Longest Increasing SubsequenceLIS,在计算机科学上是指一个序列中最长单调递增的子序列。最长上升子序列问题,就是求出一个序列中这样的子序列的长度的问题(不要求一定连续)。

2.举例了解

    先来看看一组数据:

6
1 2 4 1 3 4

    请你求出其中最长上升子序列的长度

    这是一道经典的动态规划例题,可以直接采用动态规划五步走。

1.明确问题:如题所述。
2.状态:dp[i]表示以i结尾的最长子序列的长度。
3.初始条件:dp[i]=1
4.状态转移方程 d p [ i ] = m a x ( 1 , d p [ j ] + 1 ) ( j ∈ [ 1 , i ) 且 a [ i ] > a [ j ] ) dp[i]=max(1,dp[j]+1)(j\in[1,i)且a[i]>a[j]) dp[i]=max(1,dp[j]+1)(j[1,i)a[i]>a[j])
5.答案: m a x ( d p [ i ] ) max(dp[i]) max(dp[i])

    首先,问题状态不用过多解释。

    初始条件也很容易明白,每一个数自己可以构成一个序列,也就是 d p [ i ] dp[i] dp[i]至少为 1 1 1

    接下来是状态转移方程。我们可以遍历i前面的所有数j。如果a[i]>a[j],即第i个数比第j个数小,那么就可以把第i个数接到第j个数后面。长度就变为了dp[j]+1(把第i个数接到后面去了,所以要 + 1 +1 +1)。取其中的最大值就行了。

    最后是答案。很明显,最长上升子序列有可能是以任何数结尾的。在转移状态时,我们就可以将当前状态与ans取个较大值,具体请看程序示例。

    我们将上面的样例代入一下,得到这样的 d p dp dp表:

124134
d p dp dp数组中的值123134

    请读者认真理解,以加深印象。可以尝试自己编写程序。

3.示例程序

直接输出答案:

#include<bits/stdc++.h>
using namespace std;
#define MAXN 5010 //题目中n数据范围,可以按情况改动
int main(){
	int n, a[MAXN], dp[MAXN], ans = 0; //先给ans赋一个最小值
	cin >> n;
	for (int i = 1; i <=n; i++)cin >> a[i];
	for (int i = 1; i <=n; i++){
		dp[i] = 1; //初始状态
		for (int j = 1; j < i; j++)
	        if (a[j] < a[i]) //状态转移方程
		        dp[i] = max(dp[i], dp[j]+1);
		ans = max(ans, dp[i]); //答案
	}
	cout << ans;
	return 0;
}

输出表格:

#include<bits/stdc++.h>
using namespace std;
#define MAXN 5010 //题目中n数据范围,可以按情况改动
int main(){
	int n, a[MAXN], dp[MAXN];
	cin >> n;
	for (int i = 1; i <=n; i++)cin >> a[i];
	for (int i = 1; i <=n; i++){
		dp[i] = 1; //初始状态
		for (int j = 1; j < i; j++)
	        if (a[j] < a[i]) //状态转移方程
		        dp[i] = max(dp[i], dp[j]+1);
	}
	for (int i = 1; i <= n; i++)cout << dp[i] << " ";
	return 0;
}

纯净无注释版:

#include<bits/stdc++.h>
using namespace std;
#define MAXN 5010
int main(){
    int n, a[MAXN], dp[MAXN], ans = 0;
    cin >> n;
    for (int i = 1; i <= n; i++)cin >> a[i];
    for (int i = 1; i <= n; i++){
        dp[i] = 1;
        for (int j = 1; j < i ; j++)
            if (a[j] < a[i])
                dp[i] = max(dp[i], dp[j]+1);
        ans = max(ans, dp[i]);
    }
    cout << ans << endl;
    return 0;
}

最长上升子序列

通往洛谷的传送门

题目描述

这是一个简单的动规板子题。

给出一个由 n ( n ≤ 5000 ) n(n\le 5000) n(n5000) 个不超过 1 0 6 10^6 106 的正整数组成的序列。请输出这个序列的最长上升子序列的长度。

最长上升子序列是指,从原序列中按顺序取出一些数字排在一起,这些数字是逐渐增大的。

输入格式

第一行,一个整数 n n n,表示序列长度。

第二行有 n n n 个整数,表示这个序列。

输出格式

一个整数表示答案。

输入输出样例

输入 #1

6
1 2 4 1 3 4

输出 #1

4

提示

分别取出 1 1 1 2 2 2 3 3 3 4 4 4 即可。

思路解析

    直接照搬上面的代码就行了。

喜欢就订阅此专辑吧!

【蓝胖子编程教育简介】
蓝胖子编程教育,是一家面向青少年的编程教育平台。平台为全国青少年提供最专业的编程教育服务,包括提供最新最详细的编程相关资讯、最专业的竞赛指导、最合理的课程规划等。本平台利用趣味性和互动性强的教学方式,旨在激发孩子们对编程的兴趣,培养他们的逻辑思维能力和创造力,让孩子们在轻松愉快的氛围中掌握编程知识,为未来科技人才的培养奠定坚实基础。

欢迎扫码关注蓝胖子编程教育
在这里插入图片描述


http://www.niftyadmin.cn/n/5690571.html

相关文章

C++ 多态:重塑编程效率与灵活性

目录 多态的概念 多态的定义及实现 多态的构成条件 虚函数 虚函数的重写 虚函数重写的两个例外&#xff1a; 1. 协变(基类与派生类虚函数返回值类型不同) 2. 析构函数的重写(基类与派生类析构函数的名字不同&#xff09; 析构函数要不要定义成虚函数&#xff1f;&…

Java--IO基本流

IO流 概述 生活中&#xff0c;你肯定经历过这样的场景。当你编辑一个文本文件&#xff0c;忘记了ctrls &#xff0c;可能文件就白白编辑了。当你电脑上插入一个U盘&#xff0c;可以把一个视频&#xff0c;拷贝到你的电脑硬盘里。那么数据都是在哪些设备上的呢&#xff1f;键盘…

第二十一章 (动态内存管理)

1. 为什么要有动态内存分配 2. malloc和free 3. calloc和realloc 4. 常⻅的动态内存的错误 5. 动态内存经典笔试题分析 6. 总结C/C中程序内存区域划分 1.为什么要有动态内存管理 我们目前已经掌握的内存开辟方式有 int main() {int num 0; //开辟4个字节int arr[10] …

基于vue框架的大学生四六级学习网站设计与实现i8o8z(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;学生,训练听力,学习单词,单词分类,阅读文章,文章类型,学习课程 开题报告内容 基于Vue框架的大学生四六级学习网站设计与实现开题报告 一、研究背景与意义 随着全球化进程的加速和国际交流的日益频繁&#xff0c;英语作为国际通用语言…

rabbitmq消费者应答模式

1.应答模式 RabbitMQ 中的消息应答模式主要包括两种&#xff1a;自动应答&#xff08;Automatic Acknowledgement&#xff09;和手动应答&#xff08;Manual Acknowledgement&#xff09;。 自动应答&#xff1a; 不在乎消费者对消息处理是否成功&#xff0c;都会告诉队列删…

简单易懂的springboot整合Camunda 7工作流入门教程

简单易懂的Spring Boot整合Camunda7入门教程 因为关于Spring Boot结合Camunda7的教程在网上比较少&#xff0c;而且很多都写得有点乱&#xff0c;很多概念写得太散乱&#xff0c;讲解不清晰&#xff0c;导致看不懂&#xff0c;本人通过研究学习之后就写出了这篇教学文档。 介…

Netty:高性能异步网络编程框架全解析

Netty作为一个基于Java NIO技术的开源异步事件驱动网络编程框架,已经成为开发高性能、高可靠性网络应用的首选工具之一。本文将全面介绍Netty的核心特性、架构原理以及使用方法,帮助你快速掌握这个强大的框架。 Netty的主要特点 异步事件驱动模型 Netty采用异步非阻塞的IO模型…

若依--文件上传前端

前端 ry的前端文件上传单独写了一个FileUpload.Vue文件。在main.js中进行了全局的注册&#xff0c;可以在页面中直接使用文件上传的组件。全局导入 在main.js中 import 组件名称 from /components/FileUpLoadapp.compoent(组件名称) //全局挂载组件在项目中使用 组件命令 中…