【动态规划基础】求最大连续子序列和——最大子段和

最大子段和

题目描述

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

输入格式

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

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

输出格式

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

样例

样例输入

7
2 -4 3 -1 2 -4 3

样例输出

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

基本方法

当解决最大连续子序列和问题时,可以使用两种基本方法:暴力法和动态规划法。

纯暴力

暴力法是最直观的解决方法,它通过遍历所有可能的子序列,并计算它们的和,最后返回最大的和。具体步骤如下:
初始化一个变量 m a x x maxx maxx为负无穷大,用于记录最大和。
使用两个嵌套循环遍历所有可能的子序列起点和终点。
在内层循环中,计算当前子序列的和,并将其与 m a x x maxx maxx进行比较,更新 m a x x maxx maxx
最后返回 m a x x maxx maxx作为结果。
例如,对于序列 [ − 2 , 1 , − 3 , 4 , − 1 , 2 , 1 , − 5 , 4 ] [-2, 1, -3, 4, -1, 2, 1, -5, 4] [2,1,3,4,1,2,1,5,4],暴力法将遍历所有可能的子序列,计算它们的和,并返回最大的和,即 6 6 6,对应子序列 [ 4 , − 1 , 2 , 1 ] [4, -1, 2, 1] [4,1,2,1]

暴力法的时间复杂度为 O ( n 2 ) O(n^2) O(n2),其中 n n n是序列的长度。

动态规划法

动态规划法是一种更高效的解决方法,它通过利用子问题的最优解来构建整个问题的最优解。具体步骤如下:
初始化两个变量 m a x x maxx maxx l l ll ll,分别用于记录全局最大和和当前子序列的和。
遍历整个序列,对于每个元素,将其与 l l ll ll相加,如果结果大于当前元素本身,则更新 l l ll ll为相加结果;否则,将 l l ll ll更新为当前元素。
在每次更新 l l ll ll时,将其与 m a x x maxx maxx进行比较,如果 l l ll ll大于 m a x x maxx maxx,则更新 m a x x maxx maxx l l ll ll
最后返回 m a x x maxx maxx作为结果。
例如,对于序列 [ − 2 , 1 , − 3 , 4 , − 1 , 2 , 1 , − 5 , 4 ] [-2, 1, -3, 4, -1, 2, 1, -5, 4] [2,1,3,4,1,2,1,5,4],动态规划法将遍历整个序列,计算当前子序列的和,并更新 m a x x maxx maxx l l ll ll。最终,返回 m a x x maxx maxx的值为 6 6 6,对应子序列 [ 4 , − 1 , 2 , 1 ] [4, -1, 2, 1] [4,1,2,1]

扫描二维码关注公众号,回复: 16217003 查看本文章

动态规划法的时间复杂度为 O ( n ) O(n) O(n),其中 n n n是序列的长度。

总结: 暴力法是一种简单直观的解决方法,但在处理大规模序列时效率较低。动态规划法通过利用子问题的最优解,将问题分解为更小的子问题,从而提高了效率。在实际应用中,动态规划法是解决最大连续子序列和问题的常用方法。

A C 代码

#include <bits/stdc++.h>
using namespace std;
long long n,a,ll,maxx;
int main() {
    
    
	cin >>n >>a;
	ll=a; maxx=a;
	for (int i=2;i<=n;i++)
	{
    
    
		cin >>a;
		if (ll+a<0)
			ll=0;
		else
		{
    
    
			ll+=a;
			maxx=max(maxx,ll);
		}
	}
	cout <<maxx;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/DUXS11/article/details/132269930