動態規劃 最大子段和

2022-08-16 23:09:28 字數 1873 閱讀 4160

最大子段和是乙個十分經典的問題。 

給定由n個整數(包含負整數)組成的序列a1,a2,...,an,求該序列子段和的最大值。

當所有整數均為負值時定義其最大子段和為0。

例如,當(a1,a2, ……a7,a8)=(1,-3, 7,8,-4,12, -10,6)時,

最大子段和為:23

bj是1到j位置的最大子段和:

a1a2…ai

…aj…an-1

an|《-------bj--------------》|

由bj的定義易知,當bj-1>0時bj=bj-1+aj,否則bj=aj。

則計算bj的動態規劃遞迴式:

bj=max,1≤j≤n。12

3456

a[i]

-211

-413

-5-2

b(初值=0)

-211720

1513

sum0

1111

2020

20求最大值:

1 #include2

using

namespace

std;34

int maxsum(intn)5

13return

sum;14}

1516

intmain()

17

view code

構造最優值:

1 #include2

using

namespace

std;34

const

int maxn = 1001;5

inta[maxn];67

int maxsum(int n, int &besti, int &bestj)819

if(b>sum)

2025}26

return

sum;

27 }

view code

當然上面動態規劃的演算法是最快的演算法, 時間複雜度為 o(n). 

另外還有最直接的解法: 暴力演算法

實現起來稍微更麻煩的演算法: 分治演算法

暴力解法:時間複雜度o(n^2)   即: p(n, 2) 的運算量 

#include using

namespace

std;

const

int maxn = 1001

; int

a[maxn];

int maxsum(int n, int &besti, int &bestj)

}return

best_sum;

}int

main()

view code

分治解法: 時間複雜度o( nlg(n) ) 

#include using

namespace

std;

const

int maxn = 1010

;int

a[maxn];

int findmaxcrossingsubarray(int a, int low, int mid, int

high)

}int right_sum = -0x7fffffff

; sum = 0

;

for (int j = mid + 1; j <= high; j++)

}return (left_sum +right_sum);

}int findmaximumsubarray(int a, int low, int

high)

else

}int

main()

view code

動態規劃 最大子段和

給定乙個陣列a a0,a1,a2,an 求陣列中 連續子段之和 的最大值。1 最簡單的演算法 窮舉法 計算所有的連續子段之和,得出最大值 窮舉法 計算所有的子串行和 o n 3 public static int maxsum1 int data max tmp max tmp max return...

動態規劃 最大子段和

題目描述 給出一段序列,選出其中連續且非空的一段使得這段和最大。輸入輸出格式 輸入格式 第一行是乙個正整數nn,表示了序列的長度。第二行包含n個絕對值不大於10000的整數a i,描述了這段序列。輸出格式 乙個整數,為最大的子段和是多少。子段的最小長度為1。輸入輸出樣例 輸入樣例 1 72 4 3 ...

動態規劃 最大子段和

動態規劃 最大子段和 lyk喜歡幹一些有挑戰的事,比如說求區間最大子段和。它知道這個題目有o n 的做法。於是它想加強一下。也就是說,lyk一開始有n個數,第i個數字是ai,它找來了乙個新的數字p,並想將這n個數字中恰好乙個數字替換成p。要求替換後的最大子段和盡可能大。lyk知道這個題目仍然很簡單,...