[C++] 58539--连续最大和


例题描述

一个数组有 N 个元素,求连续子数组的最大和。 例如:[-1,2,1],和最大的连续子数组为[2,1],其和为 3

  • 输入描述:
    输入为两行
    第一行一个整数n(1 <= n <= 100000),表示一共有n个元素
    第二行为n个数,即每个元素,每个整数都在32int范围内。以空格分隔。

  • 输出描述:
    所有连续子数组中和最大的值。

示例1:

  • 输入:
    3 -1 2 1
  • 输出:
    3

解题思路

本题是一个经典的动态规划问题,简称dp问题,本题题意很简单,就是求哪一段的子数组的和最大。

假设sum[i-1]是以数组中第nums[i-1]为最后一个元素的一段子数组最大和;
sum[i]是以数组中第nums[i]为最后一个元素的一段子数组最大和;
那么sum[i] = max(sum[i-1], 0) + nums[i]

理解了这个,下面代码中用sum1表示sum[i-1]sum2表示sum[i]
如果计算出更大的子数组和则保存到result中。
如果sum[i]sum2都小于0了,则置为0,因为它加上数组下一个数,不会计算出更大的子数组和。


代码实现一

#include <iostream>
#include<vector>
using namespace std;
int main(){
	int size;
	cin >> size;
	vector<int> nums(size);
	for(size_t i = 0; i < size; ++i)
		cin >> nums[i];
		
	int result = nums[0];
	int sum1 = 0, sum2 = 0;
	for (int i = 0; i < nums.size(); i++){
		// 计算到num[i]的子数组的最大和
		sum2 = sum1 >= 0 ? sum1+nums[i] : nums[i];
		if(sum2 > result)
			result = sum2;
		if(sum2 < 0)
			sum2 = 0;
		sum1 = sum2;
	}
	cout << result << endl;
	return 0;
}

代码实现二

#include <iostream>
#include <vector>

using namespace std;

int main(){
    int N;
    cin >> N;
    vector<int> v(N);
    for(int i = 0;i < N;++i)
        cin >> v[i];
        
	// F(i)初始化
    int Max = v[0];
    
	// maxsum初始化
    int maxSum = v[0];

    for(int i = 1;i < N;++i){
	    // 状态转移方程:F(i) = max(F(i-1) + array[i],array[i])
        Max = (Max >= 0 ? Max + v[i] : v[i]);
        
		// maxsum = max(maxsum,F(i))
        maxSum = max(Max,maxSum);
    }
    cout << maxSum << endl;
}

链接:https://www.nowcoder.com/practice/5a304c109a544aef9b583dce23f5f5db?tpId=85&&tqId=29858&rp=1&ru=/activity/oj&qru=/ta/2017test/question-ranking

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

giturtle

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值