当前位置:   article > 正文

《主要解析分治法——数列最大子段和》_求数列的最大子段和

求数列的最大子段和

​​​​​​​一、思路 (给定n个元素的整数列)

以数组的 center = (right-left)/2 位置处分开。形成两个子数组。

那么,最大子段和 可能出现在三个位置:

1.可能出现在 left子数组 ——>a[1,(n/2)]

2. 可能出现在 right子数组——>a[(n/2)+1,n)]

3.可能出现在 过center的 中间某部分 元素 组成的子数组

p表最左位置

q表最右位置

——>a[p,q]即1=<p=<n/2 , n/2+1=<q=<n

下面考虑 三种情况的计算方法

第一种情况: 计算 left 到 center 的最大和,记作 left_sum

第二种情况: 计算从 center+1 到 right的最大和,记作 right_sum

第三种情况: 跨边界的和。 以center为中心分别向两边计算和。

1.从 center出发,每次向左边遍历一次,就累加到lefts,如果当前的和比上次的和大,就赋给s1,一直向左直到位置 left。

2.从 center+1出发,每次向右边遍历一次步,就累加到rights,如果当前的值比上次的和 大,就赋给s2,一直向右直到位置right。

3.计算过center的连续值的和,s1+s2的和值 , 这个就是跨边界的和。

上面三种情况考虑计算完成后,最后一步就是,比较三个值中的最大值,取最大值即可。

算法一、算法二和算法四就不过多叙述了直接引用了,其大致内容都差不多

算法一部分代码:T(n)=O(n^2)

算法二部分代码:

算法四部分代码:

图例:

二、算法3代码展示

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #define N 100010
  4. //#include<bits/stdc++.h>
  5. //using namespace std;
  6. int max_sum(int a[],int n)
  7. {
  8.    return max_sub_sum(a,1,n);
  9. }
  10. int max_sub_sum(int a[],int left,int right)
  11. {
  12.     int center,i,left_sum,right_sum,s1,s2,lefts,rights;
  13.     if(left==right)
  14.     {
  15.         if(a[left>0]) return a[left];
  16.         else return (0);
  17.     }else{
  18.         center=(left+right)/2;
  19.         left_sum=max_sub_sum(a,left,center);// 左边最大子段
  20.         right_sum=max_sub_sum(a,center+1,right);// 右边最大子段
  21.     }
  22.     //求中间最大子段
  23.     s1=0;lefts=0;
  24.     for(i=center;i>=left;i--)
  25.     { // 注意:这里是从中间向左遍历,目的是为了让划分的左右两边序列能连接起来
  26.         lefts+=a[i];
  27.         if(lefts>s1) s1=lefts;
  28.     }
  29.     s2=0;rights=0;
  30.     for(i=center+1;i<=right;i++)
  31.     {
  32.         rights+=a[i];
  33.         if(rights>s2) s2=rights;
  34.     }
  35.     if(s1+s2<left_sum && right_sum<left_sum) return (left_sum);
  36.     if(s1+s2<right_sum) return (right_sum);
  37.     return s1+s2;
  38. }
  39. void display(int a[],int n)
  40. {
  41.     int i;
  42.     for(i=1;i<=n;i++)
  43.     {
  44.         printf("%d  ",a[i]);
  45.     }
  46.     printf("\n");
  47. }
  48. main(){
  49.     /*-2 11 -4 13 -5 -2*/
  50.     int n,a[N],i,sum=0;
  51.     printf("input:");
  52.     scanf("%d",&n);
  53.     for(i=1;i<=n;i++)
  54.     {
  55.         scanf("%d",&a[i]);
  56.     }
  57.     printf("output:");
  58.     display(a,n);
  59.     printf("最大子段和为:");
  60.     printf("%d",max_sum(a,n));
  61. }

三、运行结果


 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/951904
推荐阅读
相关标签
  

闽ICP备14008679号