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

2022-03-12 12:19:52 字數 2387 閱讀 2716

問題:

給定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)時,最大子段和為20。

問題求解:

方法一:列舉

學過程式設計的都會,那就是列舉i和j,求i和a[i]到a[j]之間的和的最大值。

時間複雜度o(n^3)。這顯然是不能接受滴。其實這其中進行了大量的重複計算。

#includeusing

namespace

std;

/*簡單演算法:

**v[0]不儲存資料

**t(n)=o(n^2).

*/int maxsum(int *v,int n,int *besti,int *bestj)}}

return

sum;

}int main(void

)

int r = maxsum(arr,m,&i,&j);

cout

<"

"cout

return0;

}

方法二:分治

考慮能不能有o(n*logn)的演算法呢?當然有了……

如果將給定的序列a[1..n]分成長度相等的兩段a[1..n/2]和a[n/2+1:n],分別求出這兩段的最大欄位和。則該給定序列的最大欄位和有三種情行:

1)和a[1..n/2]的最大欄位和相同。

2)和a[n/2+1:n]的最大欄位和相同。

3)最大欄位和包含兩部分,一部分在中,另一部分在a[n/2+1..n]中。

前兩種情形我們可以用遞迴方法求出,第三種情形可以分別求出兩部分的最大欄位和值再相加(注:a[1..n/2]這部分求最大欄位和要以a[n/2]結束,a[n/2+1..n] 這部分求最大欄位和要以a[n/2+1]開始)。序列的最大欄位和即為這三種情形的最大值。

這種情況下,顯然時間複雜度為o(n*logn)。要是有o(n)的演算法該多好呢?事實上還真有。這自然就是要想到動態規劃了吧!!!

#includeusing namespacestd;

/*分治法:

**將a[1n]分成a[1n/2]和a[n/2+1n],則a[1n]的最大欄位和有三種情況:

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

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

**(3)a[1n]的最大子段和為ai++aj,1<=i<=n/2,n/2+1<=j<=n

**t(n)=2t(n/2)+o(n)

**t(n)=o(nlogn)

*/int maxsum_div(int *v,int l,intr)

int s2=0;

int rights=0;

for (k=center+1;k<=r;k++)

sum=s1+s2;

if(sumsum=lsum;

if(sumsum=rsum;

}returnsum;

}int main(void)

int r = maxsum_div(arr,0,m);

coutreturn 0;

}

方法三:動態規劃

動態規劃不太好理解

#includeusing namespacestd;

int maxsum_dyn(int *a,intn)

if(temp<0)

}returnmaxn;

}int main(void)

int r =maxsum_dyn(arr,m);

coutreturn 0;

}

分析一下這個演算法,借用了乙個臨時變數temp,其實有三種情況:

1. 若temp>maxn則更新maxn,並儲存開始和結束位置;

2. 若temp<0則令temp = 0,因為temp<0則不可能繼續用temp更新最大值了;

3. 若0(temp的使用時關鍵,好好理解這種思想。理解不了也沒關係,這是比較難想的方法。)

程式設計珠璣上的經典題目,也已經被做爛了,除了最後乙個方法,其他的都是浮雲,但是最後乙個方法寫得也比較囉嗦,k完全沒必要。

int sum(int* a, int

n)

return

maxsum;

}

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

問題 給定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 時,最大子...

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

題目 給定n個整數 可能為負整數 組成的序列a1,a2,a3,a4,a5,an,求該序列子段和的最大值,子段和 定義為連續 下標遞增 的元素之和。當所有的整數均為負整數時定義其最大子段和為0。如序列為時,最大子段和為20。該問題可以用分治法或者動態規劃來求解。下面給出兩種演算法的思路及 實現 思路 ...