最大子序列求和问题

题目:

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

输入格式:

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

输出格式:

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

输入样例:

6
-2 11 -4 13 -5 -2

输出样例

20

限制条件

  时间限制

  10000 ms

  内存限制

  65536 kB

  代码长度限制

  8000 B

  判题程序

  Standard

long MaxSubSum1(const vector<int>& a) // 算法复杂度O(N³)
{
       long MaxSum = 0;
       for (int i = 0; i < a.size(); i++)
       {
              for (int j = i; j < a.size(); j++)
              {
                     long _Sum = 0; 

                     for (int k = i; k <= j; k++)
                     {
                            _Sum += a[k];
                     }
                     if (_Sum > MaxSum)
                            MaxSum = _Sum;
              }
       }
       return MaxSum;
} 

这段直接遍历 所有的子列,最大的那个自然满足要求了,理解起来没难度,但是对于O(N³)的复杂度,无论如何我们也是不能接受的。

//算法复杂度 O(N²)
long maxSubSum2(const vector<int>& a){
    long MaxSum = 0,sum;
    for(int i=0;i<a.size();++i){
        sum = 0;
        for(int j=i;j<a.size();++j){
            sum += a[j];
            if(sum > MaxSum)
                MaxSum = sum;
        }
    }
    return MaxSum;
}

优化了SubSum1的代码,仍有O(N²)的复杂度,不再赘述了。

long maxSubSum3(const vector<int>& a){
    long MaxSum = 0;
    long tmp_max =0;
    for(int i=0;i<a.size();++i){
        tmp_max += a[i];
        if(tmp_max >MaxSum)
            MaxSum = tmp_max;
        else if(tmp_max < 0)
            tmp_max = 0;
    }
    return MaxSum;
}

SubSum3只有线性复杂度 O(N),其实也非常好理解,由于是“有序”的子序列,要使子序列和变大,首先我们需要使前的项(其实是项的集合)是整数,如果是负数就直接丢弃就行了。举个极端的例子:

    数列:-1,-2,-3,-4,-5,-6,-7,8

由于前7项都是负的,我们直接丢弃就可以了。

提交subsum3 系统马上就AC了!

时间: 2024-11-05 22:00:34

最大子序列求和问题的相关文章

转~最大连续子序列求和

最大连续子序列求和详解 1.        问题描述 输入一个整数序列(浮点数序列也适合本处讲的算法),求出其中连续子序列求和的最大值. 2.        算法分析 2.1.        算法一 2.1.1.       算法描述 遍历所有子序列并求和,比较得出其中的最大值. 2.1.2.       代码描述 1          public static int maxSubSumCubic(int[] array) { 2                 int maxSum = 0

最大连续子序列求和详解

最大连续子序列求和详解 1.        问题描述 输入一个整数序列(浮点数序列也适合本处讲的算法),求出其中连续子序列求和的最大值. 2.        算法分析 2.1.        算法一 2.1.1.       算法描述 遍历所有子序列并求和,比较得出其中的最大值. 2.1.2.       代码描述 1          public static int maxSubSumCubic(int[] array) { 2                 int maxSum = 0

[C++]四种方式求解最大子序列求和问题

问题 给定整数: A1,A2,-,An,求∑jk=iAk 的最大值(为方便起见,假设全部的整数均为负数,则最大子序列和为0) 比如 对于输入:-2,11,-4,13,-5,-2,答案为20,即从A2到A4 分析 这个问题之所以有意思.是由于存在非常多求解它的算法. 解法一:穷举遍历 老老实实的穷举出全部的可能,代码例如以下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 //计算并返回所

最大子序列求和算法二三

最大子序列求和算法二 递归求解 递归求解:整个求解数组分成三部分,最大子序列可能出现在三个地方,左半部分,右半部分,跨越左右部分(包括左半部分最后一个元素,右半部分第一个元素) 分别对这三部分求解,不断的在每部分再分成三部分,递归求解 每一次递归跨越部分可以先算出,但是左,右半部分,需要不断递归,知道剩一个元素,然后回溯加上原来已经算出的跨越部分,最后返回max3(三个里面最大的一个) 时间复杂度计算 假设递归求解需要时间为T(N) ,N=1 时 T(1)=1 两个递归时间+两个for循环时间(

snnu1111(子序列求和)

1111: 子序列求和 Time Limit: 3 Sec  Memory Limit: 64 MBSubmit: 10  Solved: 2[Submit][Status][Web Board] [Edit] Description 给出n个数字,分别为1,2,3,……,n.从中选出t个数字,且这t个数字和为x的方案数为ft,x .给出m.输出下面的值: 数据满足n <= 20000,m <= min(10, n). Input 第一行输入T表示测试数据的行数.接下来T行,每行两个数字n,

子序列求和问题

问题描述:给定一整数序列A1,A2,...,An(可含负数),求A1-An中的一个子序列Ai-Aj,使得Ai-Aj的和最大,求该和的值. 涉及变量:sequence:int[]型常量,给定整数序列 n:实际元素个数 sum:int型变量,子序列之和 max:int型变量,最大子序列之和 i:int型变量,下标 涉及教材:<数据结构--Java语言描述(第2版)> 清华大学出版社 第一次看到这道题时我的思路是用三个for循环解决问题: 1.将max的初值赋为sequence[0] 2.从下标为0

力扣152,53题,最大子序列求和and积

本内容为最大子序列的求和和求积.采用DP的思路, 当前值加上小于之前值,则从该节点重新算起. 这个代码只能返回其结果值,但不能返回最后的子序列(待修改). class Solution: def maxSubArray(self,arr): #最大子数组和的DP求解 if not arr:return cur_sub,max_sub = arr[0],arr[0] #记录当前集合和最大集合 res = [arr[0]] for i in range(1,len(arr)): #从第二个开始遍历

ZOJ 3872 Beauty of Array 连续子序列求和

Edward has an array A with N integers. He defines the beauty of an array as the summation of all distinct integers in the array. Now Edward wants to know the summation of the beauty of all contiguous subarray of the array A. Input There are multiple

最大子序列求和模版

long max3(long a, long b, long c) { if (a < b) a = b; if (a > c) return a; else return c; } long maxSumRec(const vector<int>& a, int left, int right) { if (left == right) { if (a[left] > 0) return a[left]; else return 0; } int center =