7-1 最大子列和问题 (20 分)

这篇博客介绍了一种使用动态规划算法求解整数序列最大子序列和的方法。给定一个包含K个整数的序列,目标是找出所有连续子序列中和最大的那一个。博主提供了一个C++程序,该程序能够处理不同规模的数据,包括从样例的6个元素到10^5个元素的随机整数序列。程序通过维护当前子序列的总和(thissum)和最大子序列和(maxsum),在遍历序列过程中更新最大和,当当前和小于0时重置为0。最终输出最大子序列和。

给定K个整数组成的序列{ N1​, N2​, ..., NK​ },“连续子列”被定义为{ Ni​, Ni+1​, ..., Nj​ },其中 1≤i≤j≤K。“最大子列和”则被定义为所有连续子列元素的和中最大者。例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20。现要求你编写程序,计算给定整数序列的最大子列和。

本题旨在测试各种不同的算法在各种数据情况下的表现。各组测试数据特点如下:

  • 数据1:与样例等价,测试基本正确性;
  • 数据2:102个随机整数;
  • 数据3:103个随机整数;
  • 数据4:104个随机整数;
  • 数据5:105个随机整数;

输入格式:

输入第1行给出正整数K (≤100000);第2行给出K个整数,其间以空格分隔。

输出格式:

在一行中输出最大子列和。如果序列中所有整数皆为负数,则输出0。

输入样例:

6
-2 11 -4 13 -5 -2

输出样例:

20

答案:

//在线处理算法
#include <stdio.h>
int main()
{
    int n,maxsum,thissum,i;
    maxsum=thissum=0;
    scanf("%d",&n);
    int a[n];
    for(i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
        thissum+=a[i];
        if(thissum>maxsum)
        {
            maxsum=thissum;
        }
        else if(thissum<0)
        {
            thissum=0;
        }
    }
    printf("%d",maxsum);

}

 

最大问题是动态规划的一个经典问题,目标是找到给定中连续最大给定一个整数 nums,我们需要找到一个连续(可以为空),使得这个的所有元素之最大。 这个问题可以通过创建一个辅助数来解决,每个元素存储以当前位置结束的最长递增序列。算法的主要思路是遍历整个数,对于每个元素,有三种情况: 1. 如果当前元素比前一个元素小,则它的最大就是它本身,因为它需要从头开始构造一个新的序列。 2. 如果当前元素大于或等于前一个元素,那么可以保留当前元素,或者从前一个元素开始加上当前元素,取两者中的较大值,作为新序列。 3. 更新全局最大,如果当前元素加入后的新序列更大。 以下是伪代码关键步骤描述: ```python def maxSubArray(nums): # 初始化辅助数,first[i]表示以nums[i]结尾的最长递增序列的起始索引 first = [0] * len(nums) # 初始化辅助数,max_sum[i]表示以nums[i]结尾的最长递增序列 max_sum = [nums[0]] + [-float('inf')] * (len(nums) - 1) # 遍历数 for i in range(1, len(nums)): if nums[i] > nums[i - 1]: # 当前元素比前一个大,直接添加 max_sum[i] = nums[i] # 更新最长递增序列的起始索引 first[i] = i else: # 否则,寻找左边界,使得nums[i] + 左边界之前的序列最大 left = first[i - 1] # 如果nums[left]加起来比nums[i]大,说明应该从left开始 max_sum[i] = max(max_sum[i], nums[i] + max_sum[left]) # 更新起始索引,选择能提供更大的左边界 first[i] = left + 1 # 返回全局最大 return max_sum[-1] # 示例 nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4] print(maxSubArray(nums)) # 输出:6[4,-1,2,1]) ``` 相关问题-- 1. 除了动态规划,还有哪些其他解法可以解决最大问题? 2. 这种方法为什么能在O(n)时间内解决问题? 3. 对于负数的数,这种解决方案还能正常工作吗?为什么?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值