最大子段和以及最大子段和的推廣二維陣列(動態規劃)

2021-09-28 20:45:29 字數 3357 閱讀 9564

一、最大子段和問題

問題定義:對於給定序列a1,a2,a3……an,尋找它的某個連續子段,使得其和最大。定義所有負數的最大欄位和是0,由此定義,所求的最優值是: max;

1.最大欄位和問題的簡單方法(列舉的方法)

**實現:

int

summax1

(int a,

int n)

if(thissum>sum)

//用於更新最大欄位的值sum}}

return sum;

}

2.容易發現上述方法的時間複雜度是:n^3,對於上述方法改進的,容易發現最裡邊的一層迴圈可以利用次外層的迴圈代替,進而將是將時間複雜度變為 n^2.

**實現:

//一般方法改進時間複雜度是n*n

intsummax2

(int a,

int n)}}

return sum;

}

3.最大子段和的分治演算法求解

針對最大子段和的問題結構可以分為前半部分和後半部分,最終將每部分的結果合併就可以得到我們想要的結果。具體的情形可以分為以下三種情況:

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

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

(3)a[1:n]的最大欄位和是前兩種的結果的合併,就是最後的最優解。

**實現:

int

summax3

(int a,

int left,

int right)

else

int sr=0;

int rights=0;

for(

int j=center+

1;j<=right;j++

) sum=sr+sl;

if(sr>sum)

sum = leftsum;

if(sl>sum)

sum= rightsum;

}return sum;

}//傳入引數,遞迴求解

intmaxsum

(int a,

int n)

4.最大子段和的動態規劃演算法(時間複雜度最低)

主要思路:用 t 表示乙個快取資料,用sum 表示最大數,給定一維陣列,從第乙個元素開始遍歷,如果該元素大於零,就用t加上該元素,否則就將該元素賦值給t,(sum初始值是0),用sum和t進行比較。如果t大於sum,就將t賦值給sum。結束此次迴圈。用這種方法對於sum進行更新,最後返回的就是最大值。

**實現:

//動態規劃實現

intsummax

(int a,

int n)

//n是陣列的長度

else

if(b>sum)

}return sum;

}

一維情況下所有演算法實現:

#include

using

namespace std;

const

int manx=

100+5;

//動態規劃實現

intsummax

(int a,

int n)

//n是陣列的長度

else

if(b>sum)

}return sum;

}//一般方法實現

intsummax1

(int a,

int n)

if(thissum>sum)

//用於更新最大欄位的值sum}}

return sum;

}//一般方法改進時間複雜度是n*n

intsummax2

(int a,

int n)}}

return sum;

}//分治演算法求解

intsummax3

(int a,

int left,

int right)

else

int sr=0;

int rights=0;

for(

int j=center+

1;j<=right;j++

) sum=sr+sl;

if(sr>sum)

sum = leftsum;

if(sl>sum)

sum= rightsum;

}return sum;

}//傳入引數,遞迴求解

intmaxsum

(int a,

int n)

intmain

(int argc,

char

const

*ar**)

cout<<

maxsum

(a,n)

}

5.一維最大子段和的推廣,推廣到二維陣列,也就是乙個矩陣的形式,即求解乙個最大子矩陣的和是最大的。

解題思路:

由於是矩陣,例如:

1 2 3 4 5

-1 -2 4 5 6

4 3 2 1 7

可以按照同一列上的元素相加轉化為一維陣列的形式,在呼叫一維情況下的函式就可求解出結果。

**實現:

#include

using

namespace std;

const

int manx=

100+5;

intsummax

(int a,

int n)

//一維陣列下的最大子段和函式

else

if(b>sum)

}return sum;

}int

sunmax2

(int m,

int n,

int a[

][manx]

)for

(int j=i;j<=m;j++

)//按行逐步進行分解

int max=

summax

(b,n);if

(max>sum)}}

return sum;

}int

main()

} cout<<

sunmax2

(m,n,a)

}

最大子段和

設a 是n個整數的序列,稱為該序列的子串行,其中1 i j n.子串行的元素之和稱為a的子段和.例如,a 2,11,4,13,5,2 那麼它的子段和是 長度為1的子段和 2,11,4,13,5,2 長度為2的子段和 9,7,9,8,7 長度為3的子段和 5,20,4,6 長度為4的子段和 18,15...

最大子段和

問題表述 n個數 可能是負數 組成的序列a1,a2,an.求該序列 例如 序列 2,11,4,13,5,2 最大子段和 11 4 13 20。1 窮舉演算法 o n3 o n2 2 分治法 將序列a 1 n 從n 2處截成兩段 a 1 n 2 a n 2 1 n 例項 三 最大子段和 問題表述 n個...

最大子段和

再給頂的n個數的陣列中選出連續的若干個數,使得他們的和是最大的,即最大連續自序列和.列如.序列.1 2 3 1 6 5 9 結果 當取子串行 3,1,6,5,9 結果12 我的思路.1.最大連續子串行的開頭是在1.n之中.的最大連續和 2.求出以i,開頭的最大連續和,此時開頭已經確定了,那麼通過列舉...