马上要开始找工作了,做些题目练练手。
源代码:(在VC6下通过编译,正确执行)
#include <stdio.h> int FindGreatestSecSum(int *a,int len) { int sum = 0, max = 0; for(int i = 0; i < len; i++) { if(sum <= 0) sum = a[i]; else sum += a[i]; if(sum > max) max = sum; } return max; } int main() { int a[8] = {4,-3,5,-2,-1,2,6,-2}; printf("%d/n", FindGreatestSecSum(a,sizeof(a)/sizeof(int))); return 0; }
为了方便大家理解,这里转载一篇别人的解法,看了这篇文章之后,我对这个问题
的理解更加清晰了,在此向作者表示感谢。
最大子段和问题的动态规划求解
1. 基本原理
设数组为a[k],1≤k≤n,最大子段和X 被定义为:
j
X = max { ∑a[k] }
1≤i≤j ≤n k=i
不妨设:
j
b[j ] = max { ∑ a[k]}
1 ≤j ≤n k=m
其中m 是可变的。注意:a[j]必须是b[j]这个最大局部受限子段和所对应子段的最右端,
好好理解此处j 和b[j]的含义是整个算法的关键!
根据b[j]和X 的定义,不难发现:
X = max b[j ]
1≤j ≤n
另一方面,根据b[j]的定义,可以看出:
当b[j-1]>0 时,无论a[j]为何值,b[j]=b[j-1]+a[j];
当b[j-1]≤0 时,无论a[j]为何值,b[j]=a[j];
所以有:
b[j ] = max { b[j -1] +a[j ],a[j ] }
1≤j ≤n
2. 具体实例
k 1 2 3 4
a[k] 3 -4 2 10
b[k] 3 -1 2 12
其中:b[1]=a[1],b[2]=b[1]+a[2],b[3]=a[3],b[4]=b[3]+a[4] ;因此,对于数组a 而言,
最大子段和为b[4],即X=12 。
3. 编程实现
略,针对数组a 进行一遍扫描即可。算法实现的时间复杂度只有O(n)。