问题
序列s的连续子序列是原序列的子集,元素在原序列中是连续的。例如s=[−1,2,3]的连续子序列有
[−1,2,3],[−1,2],[2,3],[−1],[2],[3],[] 所有子序列的各个元素之和中最大的是5=[2,3](显然负数会使子序列之和减小)。
求序列s的最大连续子序列的和。
解法
设序列s长度为n(数组从1开始,范围[1,n])。设f(i)为s=[1,i]的最大连续子序列的和,则有状态转移方程:
f(i)=⎩⎨⎧0s[i]f(i−1)+s[i](initialize)(loop)(loop)i∈[0,n]i∈[1,n],f(i−1)≤0i∈[1,n],f(i−1)>0 (1) 初始化[1,i]之间的连续子序列和为f(i)=0;
(2) 对于元素s[i],若前i−1个元素之和f(i−1)≤0,则之前部分的子序列和会使最终的和变小(因为是负值),所以直接抛弃之前的所有序列,把s[i]作为子序列的起始,则当前最大子序列和为f(i)=s[i];
(3) 对于元素s[i],若前i−1个元素之和f(i−1)>0,则之前部分的子序列和会使最终的和变大(因为是正值),所以在之前的子序列和基础上继续累加,则当前最大子序列和为f(i)=f(i−1)+s[i];
f(n)即为序列s的最大连续子序列和。该算法的时间复杂度为O(n)。
源码
MaximumContinuousSubsequenceSum.h
MaximumContinuousSubsequenceSum.cpp
测试
MaximumContinuousSubsequenceSumTest.cpp