陣列是最常用的資料結構之一,現在我們對陣列的下標進行特殊處理,使每一次操作僅保留若干有用資訊,新的元素不斷迴圈重新整理,看上去陣列的空間被滾動地利用,此模型我們稱其為滾動陣列。其主要達到壓縮儲存的作用,一般常用在dp類題目中。因為dp題目是乙個自下而上的擴充套件過程,我們常常用到是連續的解,而每次用到的只是解集中的最後幾個解,所以以滾動陣列形式能大大減少記憶體開支。
一、二維滾動陣列
例1:0-1揹包問題
問題描述:
有 n 件物品x1, x2, …, xn , 每件物品有乙個價值和乙個重量,分別記為:
v1,v2, …vn
w1,w2, …wn
其中所有的 wi 均為整數。 現有乙個揹包,其最大載重量為m,要求從這n件物品中任取若干件(這些物品要麼被裝入要麼被留下)。問揹包中裝入哪些物品可使得所裝物品的價值和最大?
我們很容易得出狀態轉移方程:f(i,j) = max
例如,容量為10,有5個物體,
重量為3 5 1 9 7
價值為11 28 6 49 35
第十三講 動態規劃之滾動陣列 - sxyckjzh - 隨風飛揚
從推導過程中可以看出,第i階段的狀態值只與i-1階段有關,以前的資料儲存在那裡已經毫無意義。為此,我們就想到了利用滾動陣列進行優化。
具體實現時,我們可以將f陣列的空間由[0…n,0…m]改為[0…1,0…m],空間複雜度由o(nm)下降到o(2m)。在儲存過程中,我們設定乙個變數c,則語句段為:
c:=0;
for i:=1 to n do begin
c:=1-c;
for j:=1 to m do begin
f[c,j]:=f[c,j-1];
if j-t[i]>0 then
if f[1-c,j-t[i]]+p[i]>f[c,j] then f[c,j]:=f[1-c,j-t[i]]+p[i];
end;
end;
這樣,二維陣列f的第乙個下標值的取值就在0,1之間迴圈變化,實現了陣列的滾動儲存。
二、一維滾動陣列
其實,在二維滾動陣列的基礎上,我們還可以優化為一維滾動陣列,但此時滾動的方向尤其重要。例如上例的01揹包我們可以降為一維,但在遞推f[j]時應按m到0的順序,這樣才能保證推f[j]時f[j-w[i]]儲存的是狀態f[i-1,j-w[i]]的值。如上表中的第3階段的資料如下表,在遞推第4階段時,最後狀態f[10]的值是由f[10]的值和f[1]+49比較而來,此時,要保證f[1]的值是上一階段的結果,若方向向反,就很難保證此值不被更新。
第十三講 動態規劃之滾動陣列 - sxyckjzh - 隨風飛揚
相應語句段為:
for i:=1 to n do
for j:=m downto 0 do
if (j>=wi) and (f[j-wi]+pi>f[j]) then
f[j]:=f[j-wi]+pi;
這樣,新產生的資料將不斷覆蓋舊資料,實現了一維資料的滾動效果。
三、mod滾動陣列
滾動陣列應用的條件是基於遞推或遞迴的狀態轉移中,反覆呼叫當前狀態前的幾個階段的若干個狀態,而每一次狀態轉移後,都有固定個數的狀態失去作用。
滾動陣列便是充分利用了那些失去作用的狀態的空間,填補新的狀態。
mod 滾動陣列主要應用在需要呼叫多個前面的階段的狀態的情況。
例2:樓梯有n階台階,上樓可以一步上1階,也可以一步上2階,編一程式計算共有多少種不同的走法。
經過分析,此題的狀態轉移方程為:f[i]=f[i-1]+f[i-2],f[1]=1,f[2]=2
此時的f[i]只跟f[i-1]和f[i-2]有關,所以用滾動陣列可優化空間,但如何實現呼叫兩個前面的階段的狀態情況?就要用到mod滾動陣列。語句段為:
f[1]:=1;
f[2]:=2;
for i:=3 to n do
f[i mod 3]:=f[(i-1) mod 3]+f[(i-2) mod 3];
這樣,在程式執行過程中只利用了三個空間f[0],f[1]和f[2],實現了陣列的滾動效果。
滾動陣列實際是一種節約空間的辦法,可根據具體題目要求選擇相應的滾動陣列進行優化。
hdu 1024 滾動陣列優化
本題的大致意思為給定乙個陣列,求其分成 m個不相交子段和最大值的問題。解題思路 dp i j 表示前j個數分成i組,且j在第i組裡的最大值。dp i j max,前乙個表示j與j 1在i組裡,後乙個表示j單獨成組。但這道題的n很大,空間複雜度太高,所以要用滾動陣列。max dp i 1 k 就是上一...
動態規劃空間優化之滾動陣列
使用範圍 使用在遞推或動態規劃中 作用 節約空間 注意 時間上沒什麼優勢 舉例1 作用在一維陣列 普通方法 int d new int 100 d 0 1 d 1 1 for int i 2 i 100 i system.out.printf d d 99 上述方法使用100個空間 近似認為 注意,...
UITableView滾動效能優化
影響 uitableview 滾動的流暢性的原因 1 在 方法中做了過多的計算占用了 ui 執行緒的時間 2 cell裡的吃gpu 在tableview cellforrowatindexpath 中 3 cell 中 view 的組織複雜 關於第一點,首先要明白 tableview 的 這裡指 d...