Robin's Log

那能得叙曲幽静,唯有念头笑巍峨

原创 最大子序列和线性算法收藏

新一篇: 使用8253实现使用1到8弹奏歌曲 | 旧一篇: 最长公共子序列

最大子序列和线性算法
 
问题描述:
       给定整数A1, A2,……AN (可能有负数),求I到j的最大值。
例如:
       -2, 11, -4, 13, -5, -2时答案为20
 
对于这个问题的算法有很多,当然我要说的是使用“动态规划”算法实现的程序,对于这个算法,我可以说很多人都曾经想到,但是没有想全(因为我就是这样的)。还有一点对于这个问题的动态规划的解法是非常经典的,她的时间复杂度是O(n),也就是线性的。而对于穷举法它的时间复杂度可是O(n3), 这样看来可以巨大的改进了。
 
考虑这样的一个问题,我们从最简单的左边开始看,就如上面的例子,-2对于结果有影响吗?回答是没有。那么让我们看下面这样一个例子:
       6, -7, ……
       此时,我们还需要考虑6 和 –7 吗,有些人说要的,因为可能对于6,后面没有比其更大的了,是啊。问题是这样的。那么对于后面的结果分析其有影响吗?这个时候我们可以说没有影响的!
       到现在,上面是不是大家多曾经想到了呢?呵呵,我曾经就想到了,那我们为什么不把这问题,推倒后面呢?动态规划法就是解决这样的一个问题,我们知道此时前面的两个数就是一种最优的子结构(尽管只有2个数,不过是完全可以推广的。)
       书中的算法就告诉我们是如何推广的,我写这样的一篇文章的具体目的也就是为了说明以上的问题,因为我和大家一样都曾经想到了前面的算法,却没有考虑下去。以此感慨!并遗憾!
       那么书中的算法是这样的:(看这个算法之前应该先知道这个问题的“分治法”的求解,这样更让你觉得,这个算法的完美之处。)

 
Int MaxSubsequenceSum(const int A[], int N)
{
       int ThisSum, MaxSum, j;
       ThisSum = MaxSum = 0;
       For(j=0; j < N; j++)
{
              ThisSum += A[j];
              If (ThisSum > MaxSum)
                     MaxSum = ThisSum;
              Else if(ThisSum < 0)
                     ThisSum = 0;
}
return MaxSum;
}

       对于这个算法的分析(逻辑):

              从左相右相加,若结果不断的增加,那么ThisSum将同MaxSum一起增加,如果遇到负数,那么也加到ThisSum上去,但是此时ThisSum < MaxSum,那么就不加。看ThisSum是不是会回升,若一直不回升,不断或是波浪型的下降,那么当它降到0时,说明前一段与后一段是可以抛弃的。正如有 7 , -8 一样,我们可以不要这两个数,但是我们知道MaxSum依然保存着前一段的最大值,(这就是这个算法中的厉害,我认为)。然后,ThisSum将从后面开始将这个子段进行分析,若有比当前MaxSum大的子段,然后替换(此时可以彻底抛弃前一段)。这样一趟扫描结果也就出来了。
 
后记:
       对于这个问题,一开始对于分治算法,我们可能很容易想对,而对与动态规划可能我们很难想到(至少我没有那么轻易就想到了)。尽管如此,还是比较庆幸想到了其最优子结构,问题解决到此,当然对于这个问题,我们还是可以用“分治”算法,其时间复杂度为:O(nlogn),也是比较优的,当然没有上面提到的优。   

发表于 @ 2005年03月27日 21:06:00|评论(loading...)|编辑

新一篇: 使用8253实现使用1到8弹奏歌曲 | 旧一篇: 最长公共子序列

评论

#keep smiling 发表于2005-12-05 17:00:00  IP: 211.167.77.*
如果全部数据为负数,你还返回0啊,这就不对了吧!
欢迎讨论,msn:luoqintao@hotmail.com
#ZD 发表于2005-12-15 15:00:00  IP: 192.168.1.*
可以先遍历一边数组,将maxsum置成数组中最大的一个整数
然后继续
复杂度仍然是O(n)
这个方法我躺在床上想出来了,在这边找到出处了,很喜欢逆的blog
学习中......
#liuy_sea 发表于2007-01-05 11:02:20  IP: 210.22.141.*
在循环前面加一句MaxSum = A[0];就可以了:)
#allen1981813 发表于2007-03-15 17:38:30  IP: 218.80.9.*
就是阿,如果全部是<0的数,那么结果就是0了,这样问题本身就变为处理>=0的问题了。LZ,抄书抄错了吧?
#hongweijin 发表于2007-03-16 19:39:04  IP: 125.126.160.*
我写这篇文章得目的是说明我得思维方式,不是说我要去抄书。呵呵,当然我觉得假如有人愿意,我还是很喜欢看抄书的东西,只是有人可以帮助我来读书。当然这个问题是我读大学时考虑过的。差不多已经快2年了,还是算法是基本的,任何时候都有人讨论。
#touzani 发表于2007-11-15 19:08:35  IP: 61.144.54.*
顶一下~~
发表评论  


当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
Csdn Blog version 3.1a
Copyright © Robin Li