动态规划最大子段和讲解和【题解】——最大子段和

devtools/2024/10/19 19:32:01/

动态规划最大子段和讲解和【题解】——最大子段和

  • 1.详细讲解
    • 最大子段和
      • 题目描述
      • 输入格式
      • 输出格式
      • 输入输出样例
        • 输入 #1
        • 输出 #1
      • 提示
          • 样例 1 解释
          • 数据规模与约定
    • 1.1.思路解析
    • 1.2.AC代码
  • 2.优化
  • 3.别言

1.详细讲解

最大子段和

题目描述

给出一个长度为 n n n 的序列 a a a,选出其中连续且非空的一段使得这段和最大。

输入格式

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

第二行有 n n n 个整数,第 i i i 个整数表示序列的第 i i i 个数字 a i a_i ai

输出格式

输出一行一个整数表示答案。

输入输出样例

输入 #1
7
2 -4 3 -1 2 -4 3
输出 #1
4

提示

样例 1 解释

选取 [ 3 , 5 ] [3, 5] [3,5] 子段 { 3 , − 1 , 2 } \{3, -1, 2\} {3,1,2},其和为 4 4 4

数据规模与约定
  • 对于 40 % 40\% 40% 的数据,保证 n ≤ 2 × 1 0 3 n \leq 2 \times 10^3 n2×103
  • 对于 100 % 100\% 100% 的数据,保证 1 ≤ n ≤ 2 × 1 0 5 1 \leq n \leq 2 \times 10^5 1n2×105 − 1 0 4 ≤ a i ≤ 1 0 4 -10^4 \leq a_i \leq 10^4 104ai104

1.1.思路解析

    题目已经在上面讲得很清楚了,我就不再赘述。这里直接来一个动态规划五步走。

1.明确问题:如上。
2.状态:dp[i]表示以第 i i i个元素结尾的最大子段和。
3.初始条件:dp[1]=a[1]
4.状态转移方程:
d p [ i ] = m a x ( a [ i ] , d p [ i − 1 ] + a [ i ] ) dp[i]=max(a[i],dp[i-1]+a[i]) dp[i]=max(a[i],dp[i1]+a[i])
5.答案: m a x ( d p [ i ] ) ( i ∈ [ 1 , n ] ) max(dp[i])(i\in[1,n]) max(dp[i])(i[1,n])

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

    再来看看初始条件,很明显,第一个数前面没有可以接的数了,直接赋值。

    然后是状态转移方程,这里运用了一点贪心的思想。对于当前数,如果接上前面的数还不如直接使用这一个数,就直接赋值,否则取上前面的数。

    最后是答案。和最长上升子序列一样,最大的子段和有可能是以任意一个数结尾的。在转移状态时,我们就可以将当前状态与ans取个较大值。

1.2.AC代码

#include<bits/stdc++.h>
using namespace std;
#define MAXN 200010//题目中n的数据范围,可以根据实际情况更改
int main() {int dp[MAXN], a[MAXN], n, ans = INT_MIN;//ans先赋一个较小值cin >> n;for (int i = 1; i <= n; i++)cin >> a[i];dp[1] = a[1];//初始状态for (int i = 2; i <= n; i++) {dp[i] = max(a[i], dp[i - 1] + a[i]);//状态转移方程ans = max(ans, dp[i]);}cout << ans;return 0;
}

2.优化

    容易发现,每一次循环都只用到了当前的a[i]dp[i-1]。我们可以只使用两个变量存储dp[i-1]a[i],示例如下:

#include<bits/stdc++.h>
using namespace std;
#define MAXN 200010//题目中n的数据范围,可以根据实际情况更改
int main() {int dp, n, ans = INT_MIN;//ans先赋一个较小值cin >> n;for (int i = 1; i <= n; i++) {int tmp;cin >> tmp;if (i == 1) {//初始状态 dp = tmp;continue;}dp = max(tmp, dp + tmp);//状态转移方程 ans = max(ans, dp);}cout << ans;return 0;
}

3.别言

    此题还有许多的做法,例如前缀和,还有分治。因为篇幅关系。这里就不做详细讲解。感兴趣的同学可以去看看这里。

喜欢就订阅此专辑吧!

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

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


http://www.ppmy.cn/devtools/125274.html

相关文章

YoloV8改进策略:BackBone改进|CAFormer在YoloV8中的创新应用,显著提升目标检测性能

摘要 在目标检测领域,模型性能的提升一直是研究者和开发者们关注的重点。近期,我们尝试将CAFormer模块引入YoloV8模型中,以替换其原有的主干网络,这一创新性的改进带来了显著的性能提升。 CAFormer,作为MetaFormer框架下的一个变体,结合了深度可分离卷积和普通自注意力…

[Python学习日记-46] Python 中第三方开源模块的安装、使用与上传自己写的模块

[Python学习日记-46] Python 中第三方开源模块的安装、使用与上传自己写的模块 简介 下载与安装 如何使用安装好的第三方开源模块 如何上传自己写的模块到 PyPi 简介 在前面的模块介绍和导入当中主要介绍的都是 Python 内置的一些模块&#xff0c;我们把它称为标准库&#…

vue+echarts实现雷达图及刻度标注

文章目录 前言代码实现实现效果总结 前言 最近项目有做数据可视化 大屏 不免再次使用些echarts应用 记录下其中echarts雷达图的实现 代码实现 先上代码 <template><div class"container"><div ref"chart" style"width: 500px; heig…

vue中watch的用法

在 Vue.js 中&#xff0c;watch 是一个用于侦听和响应数据变化的选项。它常用于监听组件数据&#xff08;包括 props 和 data 中的值&#xff09;的变化&#xff0c;并在值发生变化时执行自定义逻辑。 基本用法 watch 选项接受一个对象&#xff0c;其中键是你想要侦听的变量&…

信息论笔记

知识点 学习视频链接 信息论简介和概率论复习 信息的定义 信息、信号、消息的概念 香农信息 信息论的研究对象和目的 信源&#xff1a;产生消息和消息序列的源编码器&#xff1a;将消息变为适合信道传输的物理量信道&#xff1a;传输或者储藏信号的媒介译码器&#xf…

计算机毕设选题推荐【软件工程专业】

计算机毕设选题推荐【软件工程专业】 对于软件工程专业的同学们来说&#xff0c;选择一个合适的毕业设计选题是成功完成毕设的第一步。一个好的选题不仅要符合当前行业的技术潮流&#xff0c;还要结合自己所学的知识与兴趣。以下是为大家整理的100个软件工程专业的毕设选题推荐…

如何搭建直播美颜平台?视频美颜SDK的核心技术详解

时下&#xff0c;美颜效果作为提升直播吸引力的重要手段&#xff0c;已经成为主播和观众的共同期待。本篇文章&#xff0c;小编将与大家分享搭建一个高效的直播美颜平台的流程&#xff0c;重点介绍视频美颜SDK的核心技术。 一、直播美颜平台的构建 搭建一个直播美颜平台&#…

SpringBoot实战教程:购物推荐网站的设计与实现

3系统分析 3.1可行性分析 通过对本东大每日推购物推荐网站实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本东大每日推购物推荐网站采用JAVA作为开发语言&…