算法分析之最大子段求和

给定由n个整数(包含负整数)组成的序列a1,a2,...,an,求该序列子段和的最大值。
当所有整数均为负值时定义其最大子段和为0。
所求的最优值为:

例如,当(a1,a2, ……a7,a8)=(1,-3, 7,8,-4,12, -10,6)时,最大子段和为:

分治方法求解
从问题的解的结构可以看出,它适合于用分治策略求解:
如果将所给的序列a[1:n]分为长度相等的两段a[1:n/2]和a[n/2+1:n],分别求出这两段的最大子段和,则a[1:n]的最大子段和有三种情形:
a[1:n]的最大子段和与a[1:n/2]的最大子段和相同;
a[1:n]的最大子段和与a[n/2+1:n]的最大子段和相同;
a[1:n]的最大子段和为下面的形式。

A、B这两种情形可递归求得。
对于情形C,容易看出,a[n/2]与a[n/2+1]在最优子序列中。因此,我们可以在a[1:n/2]和a[n/2+1:n]中分别计算出s1和s2。则s1+s2即为出现情形C使得最优值。
{1,-3,7,8,-4,12,-10,6}

C 等价于求从某个元素开始的子段和的最大值
例如:求从数组0开始的子段和的最大值

sum=0,max=0;
for(int i=0;i<=n;i++){
	sum=sum+a[i];
	if(sum>max)
		max=sum;
}

以下是整体代码:

int MaxSubSum(int a, int left, int right){
  int sum=0;
  if (left==right)sum=a[left]>0?a[left]:0;
  else{int center=(left+right)/2;
    int leftsum=MaxSubSum(a,left,center);
    int rightsum=MaxSubSum(a,center+1,right);
    int s1=0;lefts=0;
    for (int i=center;i>=left;i--){
	lefts+=a[i];
       if (lefts>s1) s1=lefts;
    }
    int s2=0;rights=0;
    for (int i=center+1;i<=right;i++){
      rights+=a[i];
      if (rights>s2) s2=rights;
    }
    sum=s1+s2;
    if (sum<leftsum) sum=leftsum;
    if (sum<sightsum) sum=rightsum;
  }
  return sum;
}

原文地址:https://www.cnblogs.com/khnl/p/11639292.html

时间: 2024-10-14 14:30:50

算法分析之最大子段求和的相关文章

1081 子段求和

1081 子段求和 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 给出一个长度为N的数组,进行Q次查询,查询从第i个元素开始长度为l的子段所有元素之和. 例如,1 3 7 9 -1,查询第2个元素开始长度为3的子段和,1 {3 7 9} -1.3 + 7 + 9 = 19,输出19. Input 第1行:一个数N,N为数组的长度(2 <= N <= 50000). 第2 至 N + 1行:数组的N个元素.(-10^9 <= N[i] <

1081 子段求和(前缀和)

1081 子段求和(前缀和)(51NOD基础题) 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 给出一个长度为N的数组,进行Q次查询,查询从第i个元素开始长度为l的子段所有元素之和. 例如,1 3 7 9 -1,查询第2个元素开始长度为3的子段和,1 {3 7 9} -1.3 + 7 + 9 = 19,输出19. Input 第1行:一个数N,N为数组的长度(2 <= N <= 50000). 第2 至 N + 1行:数组的N个元素.(-10^9 <= N

51nod 1081 子段求和

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 给出一个长度为N的数组,进行Q次查询,查询从第i个元素开始长度为l的子段所有元素之和. 例如,1 3 7 9 -1,查询第2个元素开始长度为3的子段和,1 {3 7 9} -1.3 + 7 + 9 = 19,输出19. Input 第1行:一个数N,N为数组的长度(2 <= N <= 50000). 第2 至 N + 1行:数组的N个元素.(-10^9 <= N[i] <= 10^9) 第N + 2行:1

(前缀和)51NOD 1081 子段求和

给出一个长度为N的数组,进行Q次查询,查询从第i个元素开始长度为l的子段所有元素之和. 例如,1 3 7 9 -1,查询第2个元素开始长度为3的子段和,1 {3 7 9} -1.3 + 7 + 9 = 19,输出19. Input 第1行:一个数N,N为数组的长度(2 <= N <= 50000). 第2 至 N + 1行:数组的N个元素.(-10^9 <= N[i] <= 10^9) 第N + 2行:1个数Q,Q为查询的数量. 第N + 3 至 N + Q + 2行:每行2个数,

《程序设计技术》课程辅助学习资料

本文档提供课程相关的辅助学习资料. 阅读程序是提高程序设计水平的最为有效的方法,<程序设计技术>课程至少应该阅读后面提供链接博文中的基础部分.能够阅读完基础部分的博文,则可以给课程学习奠定一个坚实的基础. 自己编写程序也是学习编程必不可少的一个环节.自己编写是否正确可以通过OJ系统来验证.选做OJ的程序设计题方便于评价自己所写的程序是否正确.想要提高编写程序的能力并且达到更高的水平,从各个OJ中选做一些编程题是十分必要的. 文中提供了CCF-CSP认证考试历年 试题的第1题的题解.这些题解中都

算法重拾之路——最大子段和

***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************** 第二章:动态规划 >最大子段和< 算法描述: ?给定由n个整数(可能为负整数)组成的序列 a1,a2, ... , an ,求该序列形如  从ai 到 aj (i ≤ j)的子段和的最大值.当所有整数均为负整数时定义其最大值为0.根据这个定义,所求的最优值为:

最大子数组和(最大子段和)

比如对于数组[1,-2,3,5,-1,2] 最大子数组和是sum[3,5,-1,2] = 9, 我们要求函数输出子数组和的最大值,并且返回子数组的左右边界(下面函数的left和right参数). 本文我们规定当数组中所有数都小于0时,返回数组中最大的数(也可以规定返回0,只要让以下代码中maxsum初始化为0即可,此时我们要注意-1 0 0 0 -2这种情形,特别是如果要求输出子数组的起始位置时,如果是面试就要和面试官问清楚) 以下代码我们在PAT 1007. Maximum Subsequen

动规讲解基础讲解四——最大子段和问题

给出一个整数数组a(正负数都有),如何找出一个连续子数组(可以一个都不取,那么结果为0),使得其中的和最大? 例如:-2,11,-4,13,-5,-2,和最大的子段为:11,-4,13.和为20. 看见这个问题你的第一反应是用什么算法? (1) 枚举?对,枚举是万能的!枚举什么?子数组的位置!好枚举一个开头位置i,一个结尾位置j>=i,再求a[i..j]之间所有数的和,找出最大的就可以啦.好的,时间复杂度? (1.1)枚举i,O(n)(1.2)枚举j,O(n)(1.3)求和a[i..j],O(n

数据结构与算法分析

数据结构:大量数据的组织方法: 算法分析:算法运行时间的估算.涉及到计算效率. 设想,如果能把时间限制从16年减至不到1秒,不很神奇吗? 在很多问题中,一个重要的观念是:写出一个可以工作的程序并不够.如果这个程序在巨大的数据集上运行,运行时间就成了重要的 问题. 算法,是为求解一个问题需要遵循的.被清楚地指定的简单 指令的集合 . 对于一个问题,一旦给定某种算法,确定其是正确的,那么接下来重要的一步就是该算法花费的时间和空间等资源量 的问题 定义:如果存在正整数c和n0,使得当N>=n0时候,T