最大子段和的兩種解法

2021-10-25 15:53:22 字數 1959 閱讀 5169

1.貪心和動態規劃

實質一樣。

前面和sum

i−

1<

0sum_<0

sumi−1

​<

0就丟掉,然後加上a

ia_i

ai​,就是以a

ia_i

ai​結尾的最大子段和。

2.分治法。

遞迴到l=r

l=rl=

r時,顯然最大子段和是a

ia_i

ai​。

對於區間[l,

r]

[l,r]

[l,r

]我們需要維護4個變數。

1.

1.1.

以l

ll為左端點的最大子段和lsu

mlsum

lsum

。2.以r

rr為右端點的最大欄位和rsu

mrsum

rsum

。3.[l,

r]

[l,r]

[l,r

]的最大子段和msu

mmsum

msum

。4.[l,

r]

[l,r]

[l,r

]的區間和sum

sumsu

m。考慮合併區間時,如果維護新區間的變數。

設新區間為[l,

r]

[l,r]

[l,r

],中點m=⌊

l+r2

⌋m=\lfloor\dfrac\rfloor

m=⌊2l+

r​⌋,左子區間為[l,

m]

[l,m]

[l,m

],右子區間為[m+

1,r]

[m+1,r]

[m+1,r

]。對於區間[l,

r]

[l,r]

[l,r

]的區間和就是左子區間和加上右區間和。

對於l su

mlsum

lsum

,有兩種情況不跨越m

mm和跨越m

mm,不跨越就是左子區間的lsu

mlsum

lsum

,否則就是左子區間和加上右區間的lsu

mlsum

lsum。rsu

mrsum

rsum

同理。而msu

mmsum

msum

也可以分跨越m

mm和不跨越m

mm討論,如果不跨越m

mm,則取兩個子區間的msu

mmsum

msum

最大值,否則取左子區間的rsu

mrsum

rsum

和右子區間的lsu

mlsum

lsum

之和。這對於多次詢問和單點修改,非常有效。

官方**

class

solution

; status pushup

(status l, status r);}

; status get

(vector<

int>

&a,int l,

int r);}

int m =

(l + r)

>>1;

status lsub =

get(a, l, m)

; status rsub =

get(a, m +

1, r)

;return

pushup

(lsub, rsub);}

intmaxsubarray

(vector<

int>

& nums)

};

最大子段和詳解(N種解法彙總)

問題的提出 給定有n個整數 可能為負整數 組成的序列a1,a2,an,求該序列連續的子段和的最大值。如果該序列的所有元素都是負整數時定義其最大子段和為0。例如,當 a1,a2,a3,a4,a5 5,11,4,13,4 2 時,最大子段和為11 4 13 20。解法一 窮舉法,即把所有可能情況一一枚舉...

最大子段和與最大子陣和 動態規劃解法

在乙個陣列中找出和最大的連續幾個數。至少包含乙個數 例如 陣列a 2,1,3,4,1,2,1,5,4 則連續的子串行 4,1,2,1 有最大的和6.輸入格式 第一行輸入乙個不超過1000的整數n。第二行輸入n個整數a i 輸出格式 第一行輸出乙個整數,表示最大的和。include includeus...

01 複雜度1 最大子列和問題 兩種解法

解法一 暴力解法,把所有的連續子列和求出來。但是如何才能把所有的子列和表示出來呢?兩個for迴圈。依次求出以陣列下標為0的元素為起始的的所有連續子列和,再接著求出以陣列下標為1的元素為起始的的所有連續子列和 第乙個for迴圈為了把所有元素走一遍,第二個for迴圈是求出含有sequence i 的所有...