利用滾動陣列優化

2021-10-04 18:15:10 字數 2078 閱讀 8017

陣列是最常用的資料結構之一,現在我們對陣列的下標進行特殊處理,使每一次操作僅保留若干有用資訊,新的元素不斷迴圈重新整理,看上去陣列的空間被滾動地利用,此模型我們稱其為滾動陣列。其主要達到壓縮儲存的作用,一般常用在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...