定义
给定一个由数字组成的序列,其中连续的一段子序列称为一个子段,子段中的所有数之和称为子段和,这里只考虑非空子段即至少包含—个元素的子段。
动态规划算法
对于全是非正数的序列,答案明显就是其中的元素的最大值。
对于有正数的序列,考虑以每一个点为结尾的最大子段和,这个子段一定满足其前缀和均非负,因为如果有一个前缀是负的,那么减掉这个前缀对于这个点一定更优,并且这个子段要尽量往前延伸。
所以我们可以只用一次扫描,记录目前统计的和sum以及答案ans。当sum加上当前位置这个数还是正数的时候就继续累加sum,否则就将sum置为0。这样就舍掉了所有前缀是负数的情况,并且保证了这个子段尽可能的长了,也就是说扫描中记录的sum就是以每一个点为结尾的最大子段和,每一次如果sum比ans大就可以更新ans。最后ans就是整体的最大子段和。
时间复杂度O(N).
int a[10005];
int sum;
int n;
int ans;
int main(){
cin >> n;
for(int i = 0; i < n; i++){
cin >> a[i];
ans = max(ans, a[i]);
}
if(ans <= 0) cout << ans;//先考虑全为非正数的情况,如果不考虑,用这种方法就会出错
else {
for(int i = 0; i < n; i++){
sum += a[i];
if(sum < 0) sum = 0;
ans = max(ans, sum);
}
cout << ans;
}
return 0;
}