最大连续子段和的两种线性算法

问题描述:给一个数组a1,a2,...,an.求这个数组的最大连续子段和。(非空子段)

 

即,定义Sij=ai+...+aj,则题目要求的是 max{Sij}(1<=i<=j<=n)

 

N^3枚举和优化之后的N^2枚举就不说了,还有NlogN的二分算法也不提,想了解的可以看我的另一篇博客:http://www.cnblogs.com/itlqs/p/5097504.html

 

这里主要详解两种O(n)的算法。

 

方法一:动态规划

  dp[i]表示以第i位为结尾的最大子段和。那么转移方程就是:dp[1]=a[1],dp[i]=max{dp[i-1]+a[i],a[i]} (i>=2)

  以第i位为结尾的最大子段和,要么是它接上了前一个的最大子段和,要么就是它自己。

  最后的结果就是扫一遍dp[1..n]的最大值。

方法二:前缀和

  前缀和Sn=a1+...+an可以预处理出来。(S0=0)

  则Sij=ai+...+aj=Sj-Si-1

  题目要求的实际上就是max{Sij}=max{Sj-Si-1}=max{Sj-min{Si-1}}(1<=i<=j<=n)

  那么也就是说,对于每一个Sj,我们都要找它前面的最小的一个前缀和减掉,那么这个min{Si-1}是可以动态维护的,所以O(n)扫一遍结果就出来了。

 

posted @ 2017-12-31 11:34  ACMsong  阅读(501)  评论(0编辑  收藏  举报