1 问题描述
由N个整数构成的一维数组A[0],A[1],A[2],...,A[N-1],找出其连续子数组中和最大的一个。连续子数组就是连续的几个元素构成的子数组。
{1, -2, 3, 10, -4, 7, 2, -5}
2 问题的解决思路
2.1 子问题的提取和描述
包含A[i]的连续子数组中最大的为sum[i],那么共有sum[0], sum[1], sum[N-1],求出这些值,然后,其中最大的即为最大和的连续子数组。这里一定要是包含i,因为这样的话,就把这个问题转化成了N个子问题。
2.2 递推关系提取
sum[0] = 1
假设sum[i-1]已知,sum[i-1]是前面的i个元素的最大值,现在加上A[i],现在分下面两种情况讨论:
第一,如果sum[i-1]<0,那么sum[i]=A[i],因为前面的都是小于0的,那么丢掉它们,加入的话,没有意义,只会把包含我的这个子串拖累掉;
第二,如果sum[i-1]>=0, 又分两种情况:
第一,如果sum[i-1] + A[i] > 0,那么说明前面的i-1的最大子串对我是有帮助的,并且我们一起对后面的A[i+1]也是有帮助的,因此
sum[i] = sum[i-1] + A[i];
第二,如果sum[i-1] + A[i] < 0,那么说明自己是一个很小的负数,对后面的A[i+1]是没有帮助的,会拖累后面的,那么
sum[i] = A[i];
2.3 列表求解
sum[i] A[i] =1 -2 3 10 -4 7 2 -5
i = 0 1
i = 1 -2
i = 2 3
i = 3 13
i = 4 9
i = 5 16
i = 6 18
i = 7 13
3 编码实现
#include <iostream>
#include <climits>
int main(int argc, char* argv[])
{
int A[8] = {1, -2, 3, 10, -4, 7, 2, -5};
int sum[8] = {0};
sum[0] = 1;
for (int i = 1; i < 8; i++)
{
if (sum[i - 1] < 0)
{
sum[i] = A[i];
} else {
if (sum[i - 1] + A[i] < 0)
{
sum[i] = A[i];
} else {
sum[i] = A[i] + sum[i - 1];
}
}
}
int max = INT_MIN;
for (int i = 0; i < 8; i++)
{
if (sum[i] > max)
{
max = sum[i];
}
}
std::cout<<"the max sum of continuous subarray is:"<<max<<std::endl;
}