MaximumContinuousSubsequenceSum 最大连续子序列和

问题

序列ss的连续子序列是原序列的子集,元素在原序列中是连续的。例如s=[1,2,3]s = [-1,2,3]的连续子序列有

[1,2,3],[1,2],[2,3],[1],[2],[3],[][-1,2,3],[-1,2],[2,3],[-1],[2],[3],[]

所有子序列的各个元素之和中最大的是5=[2,3]5 = [2,3](显然负数会使子序列之和减小)。

求序列ss的最大连续子序列的和。

解法

设序列ss长度为nn(数组从11开始,范围[1,n][1,n])。设f(i)f(i)s=[1,i]s = [1,i]的最大连续子序列的和,则有状态转移方程:

f(i)={0(initialize)i[0,n]s[i](loop)i[1,n],f(i1)0f(i1)+s[i](loop)i[1,n],f(i1)>0f(i) = \begin{cases} 0 & (initialize) & i \in [0,n] \\ s[i] & (loop) & i \in [1,n], f(i-1) \leq 0 \\ f(i-1) + s[i] & (loop) & i \in [1,n], f(i-1) \gt 0 \end{cases}

(1)(1) 初始化[1,i][1,i]之间的连续子序列和为f(i)=0f(i) = 0

(2)(2) 对于元素s[i]s[i],若前i1i-1个元素之和f(i1)0f(i-1) \leq 0,则之前部分的子序列和会使最终的和变小(因为是负值),所以直接抛弃之前的所有序列,把s[i]s[i]作为子序列的起始,则当前最大子序列和为f(i)=s[i]f(i) = s[i]

(3)(3) 对于元素s[i]s[i],若前i1i-1个元素之和f(i1)>0f(i-1) \gt 0,则之前部分的子序列和会使最终的和变大(因为是正值),所以在之前的子序列和基础上继续累加,则当前最大子序列和为f(i)=f(i1)+s[i]f(i) = f(i-1) + s[i]

f(n)f(n)即为序列ss的最大连续子序列和。该算法的时间复杂度为O(n)O(n)

源码

MaximumContinuousSubsequenceSum.h

MaximumContinuousSubsequenceSum.cpp

测试

MaximumContinuousSubsequenceSumTest.cpp

Last updated