给定K个整数组成的序列{ N1 , N2 , … , NK },“连续子列”被定义为{ Ni , Ni+1 , …, Nj },其中1≤i≤j≤K。“最大子列和”则被定义为所有连续子列元素的和中最大者。例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20。现要求你编写程序,计算给定整数序列的最大子列和。
输入格式:
输入第1行给出正整数K (≤100000);第2行给出K个整数,其间以空格分隔。
输出格式:
在一行中输出最大子列和。如果序列中所有整数皆为负数,则输出0。
输入样例:
6
-2 11 -4 13 -5 -2
输出样例:
20
思路之一
使用递归的思路,采用分而治之的方法,具体如下:
第1步:将序列从中间分为左右子列两部分;
第2步:递归求得左右子列的最大和S左,S右;
第3步:从中间分别向左右扫描,找出跨分界线的最大子列和S中;
第4步:Smax = max{S左,S右,S中};
C实现
# include <stdio.h>
int getMaxValue3(int a, int b, int c) {
return a > b ? a > c ? a : c : b > c ? b : c;
}
int divideAndConquer(int list[], int left, int right) {
//存储左右子列最大和
int maxLeftSum = 0 , maxRightSum = 0;
//存储跨边界左右子列最大和
int maxLeftBorderSum = 0 , maxRightBorderSum = 0;
//递归调用出口,子列只有一个值时
if (left == right) {
if (list[left])
return list[left];
else
return 0;
}
//计算中间索引
int center = (left + right) / 2;
//计算跨边界的左右子列最大和
int leftBorderSum = 0, rightBorderSum = 0;
//从左边扫描
for (int i = center; i >= left; i--) {
leftBorderSum += list[i];
if (leftBorderSum > maxLeftBorderSum)
maxLeftBorderSum = leftBorderSum;
}
//从右边扫描
for (int i = center+1; i <= right; i++) {
rightBorderSum += list[i];
if (rightBorderSum > maxRightBorderSum)
maxRightBorderSum = rightBorderSum;
}
//返回最大子列和
return getMaxValue3(maxLeftSum, maxRightSum, maxLeftBorderSum + maxRightBorderSum);
}
//统一函数接口
int getMaxSeqSum(int list[], int n) {
return divideAndConquer(list, 0, n-1);
}
int main(