問題描述:
給定乙個陣列,找出其中可以構成最大數的子段,需要注意的是,這個不同於最大子串行求和
—— 最大字段求和:字段必須是連續的
—— 最大子串行求和:子串行只要是包含在原來的序列中即可
舉個例子:
-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,...