求一个数组中的最大子段和

来源:互联网 发布:php开源论坛 wap 编辑:程序博客网 时间:2024/06/01 09:46

最大子段和: 数组中子段(连续的n个元素)元素累加最大的和

思路:

利用动态规划。

最大子段和构成:最大子段和对应的子段的左右相邻的子段的和一定是小于等于0的,否则,该子段的和不是最大子段和。

因此,从头至尾累加数组中元素,若出现小于0,当前子段对最大子段和为负贡献,则舍弃,从下一个元素开始累加。

max_sum 为当前最大子段和

sum为当前子段的和

a[i] 为当前元素

则:  

 sum  +=  a[i];

分以下情况:

if (sum > max_sum)  //当前子段和为最大子段和

   max_sum = sum;

if (sum < 0)  //当前子段和为负,即右部序列和<0,则重新累计

  sum = 0; 


特殊情况,若当前数组中均为负数,则最大的那个数即为最大子段和。


===========================================参考代码=============================================

#include<iostream>#include<string>using namespace std;// begin, end 用来记录最大子段和对应子段的起始和结束下标int MaxSubSegSum(int arr[], int size, int &begin, int &end) {  int max_sum = *arr;  int sum = 0;  int tmp_begin = 0;  begin = 0;  end = 0;  bool all_less_0 = true;  // 记录是否为全负数的情况  for (int i = 0; i != size; ++i) {    if(all_less_0 && arr[i] < 0) {        if (arr[i] > max_sum) {        max_sum = arr[i];        begin = end = i;      }         continue;    }    if (all_less_0) {      all_less_0 = false;    }       sum += arr[i];    if (sum > max_sum) {      max_sum = sum;      end = i;      begin = tmp_begin;    }       if (sum < 0 && i != (size - 1)) {      sum = 0;      tmp_begin = i+1;    }     }  return max_sum;}int main() {  int arr[] =                  {1, 2, -10, 5, -4, 4, 3, -9, 1};         //         {1, 2, -10, 5, -4, 4, 3, -9, 100};        //         {-10, -4, -9, -3, -22};    int size = sizeof(arr) / sizeof(*arr);    int start, end;    int max = MaxSubSegSum(arr, size, start, end);    cout << "数组内容: ";    for (int i = 0; i != size; ++i) {      cout << arr[i] << " ";    }    cout << endl <<"最大子段和为: " << max << endl         << "起始下标: " << start << endl         << "结束下标: " << end << endl         << "相应子段为: ";    for (int i = start; i <= end; ++i ) {      cout << arr[i] << " ";    }  return 0;}



           原创文章,转载请注明: 转载自    编程小径

          本文链接地址: http://blog.csdn.net/imbing/article/details/8217630



原创粉丝点击