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 的所有...