最大子段和: 数组中子段(连续的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