最大子段和問題解析

2021-09-21 15:21:51 字數 2109 閱讀 5071

題目描述:

最大子段和:給定乙個長度為n的一維陣列a,請找出此陣列的乙個子陣列,使得此子陣列的和sum=a[i]+a[i+1]+……+a[j]最大,其中i>=0,i=i,j

例如:31 -41 59 26 -53  58 97 -93 -23 84

子矩陣59+26-53+58+97=187為所求的最大子陣列。

第一種:直接窮舉法:

1     #include 2

using

namespace

std; 34

intmain()

5;

7int

sum;

8int maxsofar=0

; 9

for(int i = 0 ;i< 10;++i)//

控制子陣列開始位置

10

20}

2122 cout<

maxsofar:

"2324

return

0;

25 }

時間複雜度為o(n*n*n)

第二種:帶記憶的遞推法:

1     #include 2

using

namespace

std; 34

intmain()

5;

7int

sum;

8int maxsofar=0

; 9

int current[10

];

10 current[0]=a[0

];

11for(int i=1 ;i< 10;++i) //

首先生成個數為1,2,3……10個的陣列和

12

1516

for(int i=0;i< 10;++i)

17

25}

2627 cout<

maxsofar:

"2829

return

0;

30 }

顯然第二種方法比第一種方法有所改進,時間複雜度為o(n*n)。

第三種:動態規劃

下面我們來分析一下最大子段和的子結構,令b[j]表示從a[0]~a[j]的最大子段和。

b[j]的當前值只有兩種情況: 

(1) 最大子段一直連續到a[j] 

(2) 以a[j]為起點的子段  //如果不是第(1)種,則(1)肯定為負,捨去

還有一種情況,那就是最大子段沒有包含a[j],如果沒有包含a[j]的話,那麼在算b[j]之前的時候我們已經算出來了,注意我們只是算到位置為j的地方,所以最大子段在a[j]後面的情況我們可以暫時不考慮。

由此我們得出b[j]的狀態轉移方程為:b[j]=max,

所求的最大子段和為max; 78

int b=0,sum=a[0

]; 910

for(int i=0;i<10;i++)

11

1920

21 cout<

maxsum:

"2223

return

0;

24 }

演算法複雜度:o(n)

這個演算法只能夠求得最大子段和,不能夠明確得出最大子段的位置。

1

public

int maxsubsequence(int

array)

5int max =integer.min_value;

6int maxsub = new

int[array.length];

7 maxsub[0] = array[0];

8 max=maxsub[0];910

for (int i = 1; i < array.length; i++)

15}

16return

max;

17 }

view code

最大子段和問題

給定n個整數 可能為負數 組成的序列a 1 a 2 a 3 a n 求該序列如a i a i 1 a j 的子段和的最大值。當所給的整均為負數時定義子段和為0 分治法 分析 首先將陣列分為兩部分,最大子段和 可以在陣列的左半部分也可以在右半部分,也可以橫跨分割點,因此我們只需要用分治思想求出左邊最大...

最大子段和問題

給定n 個整數 有可能是負數 組成的序列,要求分別用蠻力法,減治法和動態規劃法,求最該序列的最大子段和,並對它們的效率進行比較分析。也稱窮舉法或列舉法,是一種簡單直接地解決問題的方法,常常基於問題的描述,所以,蠻力法也是最容易應用的方法。它依賴的基本技術是遍歷,採用一定的策略依次處理待求解問題的所有...

最大子段和問題

問題描述 給定n個整數 可能為負數 組成的序列a 1 a 2 a 3 a n 求該序列如 a i a i 1 a j 當所給的整數均為負數時定義子段和為0.如果序列中全部是負數則 最大子段和為0,依次所定義 所求的最優值max,1 i問題解析 動態規劃演算法 dp i 包含元素i的子段和 dp 0 ...