最大子段和(贪心、在线法)

题目描述

老师给笑笑布置了一份的作业,笑笑不知如何解决,找你帮忙解决。

老师给了一串很长的数列,要求从中找出连续的一段来使得总和最大。

输入格式

文件中第一行包括一个整数N,表示数列长度为N(N <= 100000)。

第二行包括N个整数来描述这个数列,每个整数的绝对值不超过1000。

输出格式

文件中只有一个整数,为最大的连续段总和。

输入样例

5
1 -2 3 1 -4

输出样例

4

 非常经典的题目

遍历数列,维护一段临时的子段和,当子段和为负的时候,丢掉从0开始重新维护

因为当子段和为负的时候,对之后的字段和肯定没有帮助,所以就不要,然后正的就一直留着,因为是正的,加上肯定越加越大,加到了负的值,没有关系,只要子段和不为负就没关系,每次子段都和结果比较,找出最大的那个

不理解直接看代码

#include<iostream>
#include<algorithm>
using namespace std;
int a[100010];
int main(){
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
    }
    int res = -1000000;
    int tmp = 0;
    for(int i=0;i<n;i++){
        tmp += a[i];
        res = max(res, tmp);
        if(tmp < 0) tmp = 0;
    }
    printf("%d", res);
    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好的,关于最大子段和问题,一个简单的算法可以是贪心算法,具体步骤如下: 1. 初始化当前最大子段和max_sum为列表中的第一个元素。 2. 初始化当前子段和当前子段的起始位置start_index为列表中的第一个元素。 3. 遍历列表中的剩余元素,对于每个元素进行如下操作: - 将当前子段和加上该元素的值。 - 如果当前子段和变为负数,则说明当前子段对于整个序列的求和起负面作用,应该舍弃。 - 如果当前子段和大于当前最大子段和max_sum,则更新max_sum和对应的起始位置start_index。 4. 返回max_sum,和start_index。 希望这个简单的算法能够帮助您解决问题。 ### 回答2: 最大子段和问题是一个经典的算法问题,主要是出一个给定数组中连续子数组的最大和。以下是一个简单的算法实现: 1. 定义三个变量:sum表示当前子段和的最大值,temp表示当前子段的和,index表示记录当前子段的起始位置。 2. 遍历数组,从第一个元素开始: a. 将当前元素加到temp中,如果temp大于sum,则更新sum的值为temp,同时记录当前位置为index。 b. 如果temp小于等于0,则将temp重置为0,同时将index设为当前位置的下一个位置。 3. 遍历结束后,sum就是最大子段和,子段的起始位置为index。 该算法基于贪心策略,累加和为负数时,说明累加到这里的子段不可能是最大子段,因此重置累加和为0,寻下一个可能的子段。同时,通过记录起始位置index,可以方便追踪最大子段的具体位置。 该算法的时间复杂度为O(n),其中n为数组的长度。该算法的空间复杂度为O(1),只需要保存三个变量的值。 例如,对于数组[1, -2, 3, 4, -1, 2, 6, -5, 4],按照以上算法进行遍历,得到最大子段和为14,起始位置为2,结束位置为6,对应子段为[3, 4, -1, 2, 6]。 ### 回答3: 最大子段和问题是指在一个整数序列中,出连续子段使得其和最大。以下是一个简单算法的自然语言描述: 1. 定义一个变量max_sum,并将其初始化为0,用于记录当前的最大子段和。 2. 定义两个变量cur_sum和start_index,cur_sum用于记录当前子段的和,start_index用于记录当前子段的起始下标。 3. 遍历整数序列中的每一个元素: - 如果当前子段的和cur_sum小于0,则将cur_sum重置为0,并将start_index更新为下一个元素的下标。即到一个新的可能的起始位置。 - 否则,将cur_sum加上当前元素的值,表示将当前元素加入当前子段。 - 如果cur_sum大于max_sum,则将max_sum更新为cur_sum,表示到了一个新的最大子段和。 4. 遍历结束后,max_sum就是最大子段和。 该算法的基本思想是遍历整个序列,并用cur_sum记录子段的和。 当cur_sum为负数时,说明当前子段对后面的子段和是负贡献的,因此将其置为0重新寻可能的起始位置。 当cur_sum为正数时,说明当前子段对后面的子段和是正贡献的,因此继续加上当前元素,并将cur_sum与max_sum比较,更新max_sum。 这个过程中,始终保持max_sum为所有遍历过的子段和的最大值。 该简单算法的时间复杂度为O(n),其中n是整数序列的长度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值