当前位置: 首页 > news >正文

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

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

  • 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.mrgr.cn/news/49373.html

相关文章:

  • springcloud之服务提供与负载均衡调用 Eureka
  • 『香驰控股』上线采购数字化平台,企企通助推农业产业化国家重点龙头提升供应链价值
  • AttributeError: ‘str‘ Object Has No Attribute ‘x‘:字符串对象没有属性x的完美解决方法
  • 【优选算法篇】双指针的优雅舞步:C++ 算法世界的浪漫探索
  • 【C++】— 类和对象(3)
  • 麒麟系统离线安装英伟达驱动
  • ThreadLocal-共享变量
  • 【微服务】springboot远程docker进行debug调试使用详解
  • 为什么Python代码需要遵守Pythonic风格?
  • MarsCode--大数和距离【中等】
  • 基于Android的小型冷库管理系统(论文+源码)-kaic
  • 第二讲、C语言的常量和变量
  • 双向广搜 [NOIP2002 提高组] 字串变换————洛谷p1032
  • 基于单片机的 16 键多功能电子琴硬件设计
  • types.MethodType
  • 使用dotnet-counters和dotnet-dump 分析.NET Core 项目内存占用问题
  • Nodejs+Vue菜鸟驿站仓库管理系统的设计与实现 (论文+源码)-kaic
  • 使用 Python 爬虫批量下载百度图片的详细教程
  • C++:模拟stack、queue
  • 【机器学习】深入浅出讲解贝叶斯分类算法