码迷,mamicode.com
首页 > 其他好文 > 详细

一维向量中连续子向量的最大和

时间:2015-04-27 01:55:30      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:

Q:一个一维向量:arr[n] = {i1,i2,i3,......,in} ,计算其连续子向量中最大和。(即截取连续的一段使得段中各元素和最大,元素有负值;子向量可以为空,即和最小为0)

A:

最初的想法是穷举,双层循环将所有连续的元素和算出来

for [i,n){
    for[j,n){
        caculate sum(arr[j],arr[j]);
    }   
}

这种方式虽然有效,但显得很蠢。

这里假设截取的区间是 arr[start, end] ,那么arr[start, end+1]的连续子向量的最大和能不能由arr[start, end]确定?

如果 arr[start, end] 符合条件的子向量(假设其最大和为maxsofar)含最后一个元素,那么arr[start, end+1]只需要看(end+1)这个位置,

如果 arr[start ,end] 符合条件的子向量不含最后一个元素,

那么arr[start, end+1]中符合条件的子向量要么是arr[start ,end]中的那个,要么是包含(end+1)这个元素的新的子向量(其最大和即arr[start,end]中含最后一个元素的最大和maxending+arr[end+1]);

所以对arr[n]有如下代码:

#define N 20
#define MAX(a,b)  (a)>(b)?(a):(b)  
static int maxsofar=0;    //表示arr[start, end]中连续子向量的最大和
static int maxending=0;   //表示arr[start, end]中含(end)元素的最大和
/*static int start = -1;*/ //start的位置暂时没找到好的确定方法
static int end = -1;
void findmax(){ int i=0; for( ; i<N; ++i){ maxending = MAX( maxending+arr[i], 0); //如果arr[start,end]中的maxending加上arr[end+1]小于0,则说明arr[start,end+1]中maxending为0; maxsofar = MAX(maxending,maxsofar); //arr[start,end+1]中的maxsofar为arr[start,end]中maxsofar 和 arr[start,end+1]中maxending的最大值; if(maxsofar==maxending) end = i; } } /*当arr[N] = {-39,45,26,-18,-92,17,-4,68,72,-2,99,4,-67,142,55,-59,19,-41,-72,13};时,输出为 maxsofar=384,end=14;*/

上述实现为线性级,效率比穷举的 n2 级要高很多。

一维向量中连续子向量的最大和

标签:

原文地址:http://www.cnblogs.com/young8848/p/4458853.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!