最大子段和之分治法

2021-10-11 18:09:48 字數 1507 閱讀 9282

問題描述:

給定乙個陣列,找出其中可以構成最大數的子段,需要注意的是,這個不同於最大子串行求和

—— 最大字段求和:字段必須是連續的

—— 最大子串行求和:子串行只要是包含在原來的序列中即可

舉個例子:

-1 4 -3 1 5 -1 4 -5 2

求上述的陣列中的最大欄位和,不難得知,最大子段和就是 10 ,也就是子段4 -3 1 5 -1 4

思路:

首先,列舉?沒有列舉解決不了的問題好吧。但是真的列舉麼?在時間和空間複雜度上都會有很大的消耗;

分治?該怎麼分治呢?由於在乙個子段中,分治的話必須將原來的陣列劃分成幾個部分,在本題中,大致有三種情況:

當最大子段和在所選的界定值左邊的時候

當最大欄位和在所選的界定值右邊的時候

當最大子段和包含所選的界定值,也就是在界定值的兩側的時候

在第一種情況下,當最大子段和位於陣列最左邊的時候,通過不斷地遞迴,保留最大的子段和,最後相加便可得到

同樣,在第二種情況下,也就是說最大子段和在右邊的時候,類似與上面的,通過不斷地遞迴,相加可以求得

第三種情況相對來說比較複雜,當界定值包含在最大子段和中的時候,看上去就是類似於與問題了,但是,根據上述的想法,取得的界定值往左右兩邊分別尋找,相加便可以求得

在每乙個劃分的區間,都是採用上述三個步驟,可以得到 max sum

**演示:

#include

#include

#define n 5

int a[n]

;int

maxsum

(int a,

int l,

int r,

int*sitel,

int*siter)

else

}//求右半部份

int j;

int csumr=

0,cright=0;

int tempr=c;

for(j=c+

1;j<=r;j++)}

//中間最大和

csum=csuml+csumr;

//位置確定

if(csum>lsum)

if(csum>rsum)

else

else

if(lsum>rsum)}}

void

input()

void

main()

結果如下所示:

小結:

在分治法解決問題的時候,不斷地拆分問題,將問題拆分成我們可以解決的問題即可,類似於上題,將問題最後拆分成最小的子集,可以直接判斷最大子段和

遞迴的思想還是很重要!!!

最大子段和之分治遞迴法

time limit 10 ms memory limit 400 kib submit statistic problem description 給定n 1 n 50000 個整數 可能為負數 組成的序列a 1 a 2 a 3 a n 求該序列如a i a i 1 a j 的子段和的最大值。當所...

分治法(2) 最大子段和

題目 給定n個元素的整數列 可能為負整數 a1,a2,an.求形如 ai,ai 1,aj i j 1 n,i j 的子段使其和為最大。當所有整數為負整數時定義其最大欄位和為0。例如當 a1,a2,a3,a4,a5,a6 2,11,1,13,5,2 最大欄位和為i 2,j 4 下標從1開始 如果直接用...

3664 最大子段和之分治遞迴法

time limit 10 ms memory limit 400 kib problem description 給定n 1 n 50000 個整數 可能為負數 組成的序列a 1 a 2 a 3 a n 求該序列如a i a i 1 a j 的子段和的最大值。當所給的整數均為負數時定義子段和為0,...