最大子列和 (Theta(N))

最大子列和问题,即给定N个整数的序列({A_1,A_2,ldots,A_N }),求函数(f(i,j)=maxlbrace 0,sum_{i=0}^n A_krbrace)的最大值。 例如(lbrace-2,11,-4,13,-5,-2rbrace)的最大子列和为20,子列为(lbrace11,-4,13rbrace). (lbrace-10, 1, 2, 3, 4, -5, -23, 3, 7, -21rbrace)的最大子列和为10,子列为(lbrace1,2,3,4rbrace)。 本文将给出实现这种算法的(Theta(N^2))(Theta(N))算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int (int A[], int N)
{
int ThisSum,MaxSum=0;
int i,j;
for(i=0;i<N;i++)
{
ThisSum=0; //ThisSum是从A[i]到A[j]的子列和
for(j = i; j < N; j++)//j是子列右端位置
{
ThisSum += A[j]; //对于相同的i,不同的j,只要在j-1次循环的基础上累加1项即可
if(ThisSum > MaxSum) //如果刚得到的这个子列和更大
MaxSum = ThisSum; //则更新结果
}
}
return MaxSum;
}

(Theta(N))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int (int A[], int N)
{
int ThisSum, MaxSum;
int i;
ThisSum = MaxSum = 0;
for(i = 0; i < N; i++)
{
ThisSum += A[i]; //向右累加
if(ThisSum > MaxSum)
MaxSum = ThisSum; //发现更大和则更新当前结果
else if(ThisSum < 0) //如果当前子列和为负
ThisSum = 0; //则不可能使后面的部分和增大,抛弃之
}
return MaxSum;
}

第二种方法可能不是很好理解,有必要的话可以根据上面的例子手动推演一下。