求最大子序列和

問題:給定整數序列S[0],S[1],... S[N-1],子序列和是指S[i]+S[i+1]+...+S[j-2]+S[j-1],其中i,j, 0<= i <= j <= N-1,求所有這樣的子序列和的最大值,即最大子序列和。


方法一:枚舉法 O(N^2)


求出所有的子序列和,取其最大值。算法複雜度爲O(N^2)。

int maxSubSeq1(int a[], int len) 
{ 
	int maxSum;
	int i, j;

	if (len <= 0)	return MIN_INT; /* MIN_INT可取足夠小的整數 */

	maxSum = a[0];
	for (i = 0; i < len; ++i) { 
		int thisSum = 0;
		for (j = i; j < len; ++j) {
			thisSum += a[j];
			maxSum = (thisSum > maxSum ? thisSum : maxSum);
		}
	} 
	return maxSum; 
}


方法二:動態規劃 O(N)


這個問題可以採用動態規劃來解答。假設對N個數的序列S[0…N-1],最大子序列和爲F(N),令M(N)爲包含S[N-1]的最大子序列和。當已求得F(N-1)時,考慮S[N-1],最大子序列可能有以下兩種情況,一是包括S[N-1],一是不包括S[N-1]。不包括S[N-1]時,F(N) = F(N-1);包括S[N-1]時,F(N) = M(N)。


所以 F(N) = max{ F(N-1), M(N) }。


現在的問題就剩下求M(N)了,而 M(N) = max{ M(N-1)+S[N-1], S[N-1] }

即,M(N) = (M(N) > 0 ? (M(N) + S[N-1]) : S[N-1]);


算法複雜度爲O(N)

int maxSubSeq2(int a[], int len)
{
	int maxSum, lastMaxSum;
	int i;

	if (len < 0)	reutrn MIN_INT; /* MIN_INT可取足夠小的整數 */
	maxSum = a[0];
	lastMaxSum = a[0];
	for (i = 1; i < len; ++i) {
		lastMaxSum = (lastMaxSum > 0 ? lastMaxSum + a[i] : a[i]);
		maxSum = (lastMaxSum > maxSum ? lastMaxSum : maxSum);
	}
	return maxSum;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章