最大非空陣列問題
1.分解:將問題劃分為規模更小的自問題。
2.解決:遞迴的地解出子問題。
3.合併:將子問題的解組合成原問題的解。
1.代入法
2. 遞迴樹法
3. 主方法
找出陣列的最大連續非空子陣列
複雜度 θ(n^2)
偽**
max_subarry(a)
max = -infinity
for i = 0 to a.length
sum = 0
for j = i to a.length
sum = sum + a[j]
if sum > max
max = sum
low = i
high = j
return (low,high,max)
c++
#include
using
namespace std;
int low,high;
intmax_subarray
(int
*x,int n)}}
return max;
}int
main()
思路
分解:二分法分解,最大子陣列有三種情況:
– 在左邊的子陣列
– 在右邊的子陣列
– 跨越了中點
解決:未跨越中點:遞迴,最小規模為乙個元素
跨越中點:左右限定乙個邊解找最
合併:比較三種情況找出的最大。
偽**
max_crossing_subarray(a,low,mid,high)
left_sum=-infinity
sum=0
for i=mid downto low
sum=sum+a[i]
if(sum>left_sum)
left_sum=sum
max_left=i
right_max=-infinity
sum=0
for i=mid+1 to high
sum=sum+a[i]
if(sum>right_sum)
right_sum=sum
max_right=i
return (max_left,max_right,left_sum+right_sum)
max_subarray(a,low,high)
if low==high
return (low,high,a[low])
else
mid=(low+high)/2
(left_low,left_high,left_sum)=max_subarray(a,low,mid)
(right_low,right_high,right_sum)=max_subarray(a,mid+1,high)
(across_low,across_right,across_sum)=max_acrossing_subarray(a,low,mid,high)
if left_sum>=right_sum and left_sum>=across_sum
return (left_low,left_high,left_sum)
else if right_sum>=left_sum and right_sum>=across_sum
return (right_low,right_high,right_sum)
else
return (across_low,across_high,across_sum)
c++原始碼
#include
using
namespace std;
int*
max_acrossing_subarray
(int
*x,int low,
int mid,
int high)
} sum=0;
for(i=mid+
1;i<=high;i++)}
ret[2]
=left_sum+right_sum;
return ret;
}int
*max_subarray
(int
*x,int low,
int high)
intmain()
演算法導論 分治法
分治法的思想 分 將問題分解為規模更小的子問題 治 將這些規模更小的子問題逐個擊破 合 將已解決的子問題合併,最終得出 母 問題的解 例如 將乙個陣列a,從小到到大排序。分治思想 我們可以將陣列a分成2個陣列,即a 0.a.length 2 a a.length 2 1,a.length 分別將它們...
演算法導論 第四章 分治策略 (6)分治策略概述
當子問題足夠大,需要遞迴求解時,稱之為遞迴情況。當子問題變得足夠小,不再需要遞迴時,我們說遞迴已經 觸底 進入了基本情況。遞迴式與分治方法是緊密相關的,因為使用遞迴式可以很自然的刻畫分治演算法的執行時間。乙個遞迴式就是乙個等式或不等式,它通過更小的輸入上的函式值來描述乙個函式。子問題的規模不必是原問...
演算法導論 第四章 分治策略 速記
在分治策略中,我們遞迴的求解乙個問題,在每層遞迴中應用如下三個步驟 分解 divide 步驟將問題劃分為一些子問題 子問題的形式與原問題一樣,只是規模更小.解決 conquer 步驟遞迴地求解出子問題,如果子問題的規模足夠小,則停止遞迴,直接求解.合併 combine 步驟將子問題的解組合成原問題的...