根据中国MOOC大学上浙大的数据结果课程给出的 在线处理 算法,在此对该算法的思路再进行一遍梳理
- 题目要求求出子序列的最大和,那么如何确定该子序列呢
- 首先,对于随便一个子序列,假设当前序列和ThisSum已经小于0,那么对于它的前后任何一个序列,都是不应该把它加上去的,因为这样之后会让新的序列和减小;
所以,序列和为负数的子序列需要抛弃
换句话说,序列和为负数的子序列,不能参与到其他序列中,它是独立的,我们只能可以在它中间再缩小范围,找到一个和的最大值 - 那么,根据2的分析,对于给出的序列,完全可以将其分为若干个序列和为负数的子序列,注意最后的一个序列和不一定是负数,这些子序列互不干涉,只需分别找出它们和的最大值,在选其中最大的即可
- 举例来说,对于序列-1 3 -2 4 -6 1 6 -1,我们将其分为
-1 3 -2 4 -6 1 6 -1
这样划分之后,第一块MaxSum为-1,第二块为5,第三块为7
而对于这三块Max的计算,可以使用一个for循环完成
代码如下
#include <iostream>
using namespace std;
const int MAXN = 1e+5 + 5;
int num[MAXN] = {0};
int main() {
int N, flag = false; //输入全负数则flag为flase
scanf("%d", &N);
for(int i = 0; i < N; i++) {
scanf("%d", &num[i]);
if(num[i] > 0) flag = true; //不是全负数
}
if(false == flag) { printf("0"); return 0; }
int MaxSum = 0, ThisSum = 0;
for(int i = 0; i < N; i++) {
ThisSum += num[i]; //向右累加
if(ThisSum < 0) ThisSum = 0;//若当前子列和为负,抛弃
if(ThisSum > MaxSum) MaxSum = ThisSum;
}
printf("%d", MaxSum);
}
这个代码基本是照搬老师给的代码