动态规划之——最大连续子序列和(C++实现)
最大连续子序列和,或称为“连续子序列的和的最大值”,是一种动态规划问题,下面来看问题描述
给定一个长度为n数字序列A1, A2, A3······An, 现要求求出一组(i,j),使得:Ai + ······ + Aj 的和最大,输出这个最大和
测试用样例见下
输入:
6
1 -3 5 8 -100 52
4
-2 85 -15 62
5
1 2 -5 6 -9 1
输出:
52
132
6
接下来开始讲解
用双重循环暴力枚举 i,j 靠谱吗?枚举(i,j)需要 O(n²) 的复杂度,计算 Ai + ······ + Aj 需要 O(n) 的复杂度,乘起来是立方阶 O(n³), 令人难以接受
暴力枚举 ,pass !
接下来考虑动态规划的做法,开一个dp数组,以dp[i]来表示以A[i]结尾的最大子序列和(注意是强制以A[i]结尾),那么答案显然就是max(dp[1], dp[2], ······ ,dp[n])了,可是能一目了然的看出来的貌似只有dp[1],它的值显然等于A[1],其他的又该怎么办呢?
在动态规划题目中,能用眼睛看出答案的部分往往是这个问题的边界 ,是状态转移方程的起点,这也是动态规划的妙处所在:以边界处渺小的信息量,通过状态转移方程,逐步推出整个问题的解
一旦确定了状态转移方程和边界,距离AC这道题目就不远了!
而状态转移方程是动态规划问题的绝对核心,类型繁多,甚至往往需要就题论题,掌握它可以说是任重而道远(博主在写这篇博文时也在全身心投入动态规划的学习)
然而本题的状态方程并不复杂,对于dp[i] (i >= 2) 来说,dp[i - 1]的正负直接决定了dp[i]的取值,若dp[i - 1]为正,那么dp[i]就等于A[i]本身加上dp[i - 1],若dp[i - 1]为负,那么dp[i]就等于A[i]本身
更简单的来说,dp[i] = max{ dp[i - 1] + A[i], A[i] }
有了边界和状态转移方程,接下来,上代码!