[18/12/01]最大子段和(分治法)

问题描述:给定一个n(n>=1)个整数序列,求出其中最大连续子段和。例如:序列(-2,11,-4,13,-5,-2)的最大子序列和为20。其最大子序列是:(11,-4,13)

  【思想】 若n=1(即序列中只有1个元素),若该元素大于0,则返回该元素;否则返回0(定义一个序列的最大连续子段和至少为0,若元素全为负数,定义其和为0);

   (1)、该子序列完全落在左半部,即a[0...mid]中,采用递归求最大连续子段和maxLeftSum;

   (2)、该子序列完全落在右半部,即a[mid+1...n-1]中,采用递归求最大连续子段和maxRightSum;

   (3)、该子序列跨越a的中部而占据左右部分,以中间元素a[mid](假设它属于左边)为界,向左边部分和右边部分扩张,以左边为例,定义leftBorderSum=0,maxLeftBorderSum=0

 让leftBorderSum从中间让左边累加,如果遇到正数就把正数加上去,并把结果赋值给maxleftBorderSum (表现形式就是如果leftBorderSum>maxLeftBorderSum说明加了个正数);

右边同样的道理。最后 maxMidSum=maxleftBorderSum+maxRightBorderSum

  (4)、比较出(1)(2)(3)中所求的数那一个最大即为所求结果。

   【伪代码】

         maxSubSum(a, left, right){

            if(left=right)  Then returna[left] (值为负数返回值为0);

            else{            

                         mid=(left+right)/2;
                         maxLeftSum = maxSubSum(a,left,mid); //递归处理左右2部分
                         maxRightSum= maxSubSum(a,mid+1,right);

 

                         maxLeftBorderSum=leftBorderSum+a[i]; //从中间往左,遇到正数累加

                         maxRightBorderSum=rightBorderSum+a[j]; //从中间往右,遇到正数累加

                         maxMidSum=maxLeftBorderSum+maxRightBorderSum;

                }

                 return   max (maxLeftSum,maxRightSum,maxMidSum);

        }

【代码示例】

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 
 5 int max(int a,int b,int c){ //求3个数中的最大值
 6     int temp=(a>b)?a:b;
 7     int max=(temp>c)?temp:c;
 8     return max;
 9 }
10 
11 int maxSubSum(int a[],int left,int right){
12     if(left==right){
13           if(a[left]>0){
14             return a[left];
15           }else{
16             return 0;
17           }
18     }else{
19         int mid=(left+right)/2; //中间点的下标 ,向下取整
20         int maxLeftSum = maxSubSum(a,left,mid); //不跨界的情况下,左边的最大子段和 ,用递归
21         int maxRightSum= maxSubSum(a,mid+1,right);// 不跨界的情况下,右边的最大子段和
22 
23         int leftBorderSum=0,maxLeftBorderSum=0; //跨边界的情况 左边界 最大左边界
24         int rightBorderSum=0,maxRighBorderSum=0;
25         for(int i=mid;i>=left;i--){ //从中间往左,遇见负数总和必然变小,不加。遇到正数,加上
26             leftBorderSum=leftBorderSum+a[i];
27             if(leftBorderSum>maxLeftBorderSum)
28                 maxLeftBorderSum=leftBorderSum;
29         }
30 
31         for(int j=mid+1;j<=right;j++){ //从中间往右
32             rightBorderSum=rightBorderSum+a[j];
33             if(rightBorderSum>maxRighBorderSum)
34                 maxRighBorderSum=rightBorderSum;
35 
36         }
37 
38         return max(maxLeftSum,maxRightSum,maxLeftBorderSum+maxRighBorderSum); //比较3个数的最大值
39 
40 
41     }
42 }
43 
44 int main()
45 {
46     int a[6]={-2,11,-4,13,-5,-2};
47     printf("max=%d",maxSubSum(a,0,5));//0和5分别为数组大小为6的a数组的最左下标和最右下标
48     return 0;
49 }

【结果示例】

  

 

转载于:https://www.cnblogs.com/ID-qingxin/p/10052994.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ava实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),可运行高分资源 Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值