先给出题目图片:
简要描述一下题目就是:给出一串数字序列,让你在里面找一串相连的数字,它们的和是所有相连的数字中最大的。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1231
这个问题怎么解决呢?当然你可以枚举,找出所有的子序列,把每个子序列的和都算一遍,在找到里面最大的。这方法是可行的,但缺陷是时间复杂度太大。
现在我们讲讲用动态规划的思路:
先给出一串数字 : -9 1 -5 4 3 -6 7 8 -2
思路:用DP[i]表示以第i个元素(记为A[i])为结尾的连续子序列的最大值。(注意一定是以第i个元素为结尾,这个理解错了就不能理解整个算法思路)。
然后当DP[i-1] <0 时 DP[i] = A[i] ,
当DP[i-1]>=0时 DP[i] = DP[i-1] + A[i] 。
一句代码描述就是:DP[i] = ( DP[i-1]>=0 ? DP[i-1]+A[i] : A[i] )
然后DP【0】表示没有数字,故DP【0】 = 0 ;
有了递归方程就可以计算了。
根据上诉思路求出数字串 : -9 1 -5 4 3 -6 7 8 -2 各个位置的DP[i]
DP【0】 = 0 ;
DP【1】 = A[1] + DP[0] = -9 ; // DP[0] = 0
DP【2】= A[2] = 1 ; // DP【1】=-9< 0
DP【3】= DP[2] + A【3】 = -4 ; // DP【2】= 1 >0
DP[4] = A[4] = 4 ; // DP【3】 = -4 <0
....
....
写出所有DP[i]如下图:
找出DP【i】中最大为16 ,故上诉数字最大连续子序列的和为16.
且知道是由4 3 -6 7 8 组成。
最后解释一下DP【i】为什么是以A[i] 为结尾的连续子序列呢?
这是因为如果结尾不是A[i]的话,在考虑是否加进A[i+1]的时候就不能保持连续的性质了。这是理解这个思路比较重要的点。理解了这个这个算法也就不难理解了。