分治法 動態規劃 最大子段和

2021-09-27 21:59:46 字數 1597 閱讀 5527

題目:給定n個整數(可能為負整數)組成的序列a1,a2,a3,a4,a5,..an,求該序列子段和的最大值,「子段和」定義為連續(下標遞增)的元素之和。當所有的整數均為負整數時定義其最大子段和為0。如序列為時,最大子段和為20。

該問題可以用分治法或者動態規劃來求解。下面給出兩種演算法的思路及**實現

思路:將所給的序列分為長度相等的兩部分[1,n/2]和[n/2+1,n],分別求出這兩部分的最大子段和,整個序列的最大欄位和有三種情形:

(1)[1,n]的最大子段和與[1,n/2]的最大子段和相同

(2)[1,n]的最大子段和與[n/2+1,n]的最大子段和相同

(3)[1,n]的最大子段和為a(i)+a(i+1)+a(i+2)+...+a(j),且1 <= i <= n/2,n/2+1 <= j <= n。

對於(1)(2)可遞迴求得,對於情形(3),可看出a[n/2]與a[n/2+1]在最優子串行中。因此,可以在[1,n/2]中計算出s1(範圍是i~n/2之間),並在[n/2+1,n]中計算出s2(範圍在n/2+1~j之間),則s1+s2即為出現情形三(3)時的最優解。

**實現:

//最大子段和

int maxsubsum(int arr,int left,int right)

} int s2=0;

int rights=0;

for(int i=mid+1;i<=right;++i)

}sum=s1+s2;

if(sum執行結果如圖: 

該演算法的計算時間t(n)滿足典型的分治演算法遞迴式:

解此遞迴方程可知,t(n)=o(nlogn)。 

思路:遍歷序列,定義變數b[j](注意這並不是陣列,而是乙個int型變數)為截止到當前遍歷點的最優解,由其定義可知,當b[j-1]>0時,b[j]=b[j-1]+a[j],否則b[j]=a[j]。由此可得計算b[j]的動態規劃遞迴式為:

b[j]=max, 1 <= j <= n

**實現:int maxsum(int arr,int n)

if(b>sum) sum=b;

} return sum;

}int main()

; int n=sizeof(arr)/sizeof(arr[0]);

int res=maxsum(arr,n);

cout執行結果截圖: 

顯然,該動態規劃需要o(n)計算時間和o(n)空間。 

通過上述分析,求解該問題時,無論是從演算法的時間複雜度還是**編寫的難易程度來看,動態規劃演算法要更勝一籌。

最大子段和問題(分治法和動態規劃)

什麼是最大子段和,通俗點講 最大子段和就是給了一些數,然後你從中找了幾個連續的數,這組連續的數的和比任意一組連續的數的和都大,那麼你找的這幾個連續的數的和就是這些數的最大子段和。通俗的聽不懂你就看這裡 給定由n個整數 可能為負整數 組成的序列 分治法思想 如果將所給的序列a 1 n 分為長度相等的兩...

最大子段和 分治與動態規劃

問題 給定n個整數 可能為負數 組成的序列a 1 a 2 a 3 a n 求該序列如a i a i 1 a j 的子段和的最大值。當所給的整均為負數時定義子段和為0,依此定義,所求的最優值為 max,1 i j n 例如,當 a1,a2,a3,a4,a4,a6 2,11,4,13,5,2 時,最大子...

最大子段和 分治與動態規劃

問題 給定n個整數 可能為負數 組成的序列a 1 a 2 a 3 a n 求該序列如a i a i 1 a j 的子段和的最大值。當所給的整均為負數時定義子段和為0,依此定義,所求的最優值為 max,1 i j n 例如,當 a1,a2,a3,a4,a4,a6 2,11,4,13,5,2 時,最大子...