[每日一题] 10. 连续最大和(动态规划、贪心)

1. 题目来源

链接:连续最大和
来源:牛客网

2. 题目说明

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

输入描述:

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

输出描述:

所有连续子数组中和最大的值。

示例1

输入
3 -1 2 1
输出
3

3. 题目解析

本题是一个经典的dp问题,比较基础简单,但经常会考察。本题题意很简单,就是求哪一段的子数组的和最大。
假设sum[i-1]是以数组中第nums[i-1]为最后一个元素的一段子数组最大和,sum[i]是以数组中第nums[i]为最后一个元素的一段子数组最大和, 那么 s u m [ i ] = m a x ( s u m [ i − 1 ] , 0 ) + n u m s [ i ] sum[i] = max(sum[i-1], 0) + nums[i] sum[i]=max(sum[i1],0)+nums[i]理解了这个,下面代码中用sum1表示sum[i-1],sum2表示 sum[i],如果计算出更大的子数组和则保存到result中。如果sum[i],及sum2都小于0了,则置为0,因为加上数组下一个数,不会计算出更大的子数组和。

4. 代码展示

#include <bits/stdc++.h>

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;
}

2021 04 22 更新。

经典且简单 dp

#include <bits/stdc++.h>

using namespace std;

const int N = 1e5+5;

int n;
int a[N];
int f[N];

int main() {
    cin >> n;
    for (int i = 0; i < n; i ++ ) cin >> a[i];
    
    f[0] = a[0];
    for (int i = 1; i < n; i ++ ) f[i] = max(f[i - 1] + a[i], a[i]);
    cout << *max_element(f, f + n);
    
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Ypuyu

如果帮助到你,可以请作者喝水~

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

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

打赏作者

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

抵扣说明:

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

余额充值