zoukankan      html  css  js  c++  java
  • 算法分析之最大子段求和(一)

    给定由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;
    }
    
  • 相关阅读:
    Maven 学习笔记——Maven和Eclipse(2)
    Maven 学习笔记——Maven环境配置(1)
    Selenium WebDriver VS Selenium RC
    ASP.NET_SessionId
    'NuGet.VisualStudio.Interop 报错
    HTTP Error 403.14 Forbidden
    关于Python字符编码encode和decode
    zabbix安装步骤
    centos7 上搭建私有云
    Python读写改Excel的方法
  • 原文地址:https://www.cnblogs.com/khnl/p/11639292.html
Copyright © 2011-2022 走看看