1D 1D的動態規劃 單調佇列優化

2021-09-26 21:31:41 字數 3435 閱讀 1133

我僅一屆平凡人

對於某些dp的狀態轉移方程,我們可以寫成一種形式:

f [i

]=

min⁡l(

i)≤j

≤r(i

)f[i] = \min_ \

f[i]

=minl(

i)≤j

≤r(i

)​在這種模型中,j取值的範圍都是關於i的一次單調函式val

(i,j

)val(i, j)

val(i,

j)是關於i,j的多項式函式。我們將其稱為1d/1d的動態規劃。在上述模型中,如果多項式val

(x,y

)val(x, y)

val(x,

y)的每一項僅與i或j中的一項有關,我們可以使用單調佇列進行優化。

李煜東藍皮書上,給出三個例子。

例1:

給定乙個n長度的序列(有負數),選擇乙個長度不超過m的子段,使子段的所有數的和最大。

我處理出字首和s[i

]s[i]

s[i]

答案可以表述成:

a ns

=max⁡1

≤i≤n

}ans = \max_\ \ \}

ans=

max1≤i

≤n​}

此時我們發現它符合上述模型。那麼,我們是怎麼通過單調佇列進行優化的呢?我們不妨設兩個位置j,k並滿足:k < j < i。並且s[k

]≥s[

j]

s[k]\ge s[j]

s[k]≥s

[j]這時,我們可以知道:k絕對不可能是最優解。這不僅取決於j的字首和比k小而j更優。還因為j的位置比k靠前(長度更短),我們在後期有更多的空間選擇。此時我們將所有決策按照遍歷順序,維護成乙個單調遞增的佇列。可以知道:最優子結構由且僅由佇列中的決策產生。

藍皮書給出的**:

int l =

1, r =1;

q[i]=0

;for

(int i =

1; i <= n; i++

)

這個例子其實僅是乙個單調佇列的題目,不怎麼涉及dp。

例2:poj 1821 fence

我們設f[i

,j

]f[i, j]

f[i,j]

為考慮前i個工匠,刷前j個木板,能獲得的最大報酬。我們可以寫成轉移方程:

f [i

,j]=

max⁡j−

li≤k

≤si−

1f[i, j] = \max_ \

f[i,j]

=maxj−

li​≤

k≤si

​−1​

這裡注意摒棄i的干擾,這裡的i只是表示階段,不參與當前階段的決策。這裡的k是模型中的j,這裡的j是模型中的i。

對與每乙個階段,我們發現,隨著j的遞增,j−l

ij-l_i

j−li

​線性遞增,且val函式符合模型中的定義,可以使用單調佇列優化!這時,我們隨意找出兩個位置k1,

k2(k

1

−1

)k_1,k_2(k_1 < k_2 < s_i-1)

k1​,k2

​(k1

​​​−1)

且k

2k_2

k2​的決策優於k

1k_1

k1​此時k

1k_1

k1​為完全無用的決策。所以我們依靠轉移方程維護乙個遞減的單調佇列。

在這個題中,我們可以看到,首先對於每乙個i階段,我們初始化單調佇列:

int l =

1, r=0;

for(

int k =

max(

0, a[i]

.s - a[i]

.l); k <= a[i]

.s -

1; k++

)

我們在j−l

i≤k≤

si−1

j-l_i \le k \le s_i - 1

j−li​≤

k≤si

​−1的範圍內初始化單調佇列。因為右端點是不變的。我們只有縮左端點就行了。

for

(int j =

1; j <= n; j++

)}

下面是完整ac**:

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace std;

struct node

a[110];

int f[

110]

[16005

], q[

16005];

bool

cmp(node a, node b)

intcalc

(int i,

int k)

intmain()

for(

int j =

1; j <= n; j++)}

}printf

("%d\n"

, f[m]

[n])

;return0;

}

例3:o(nm)解多重揹包。

對於多重揹包,我們處理樸素的計數,還可以通過二進位制壓縮進行優化,但是使用單調佇列優化,我們可以講複雜度衰減為o(nm)。

我們通過模擬樸素多重揹包發現:在每個階段,每次狀態的轉移的位置都是成倍的。例如。對於p

pp點,他只能轉移到p+v

i,p+

2∗vi

,p+3

∗v

ip+v_i,p+2 * v_i, p+3*v_i

p+vi​,

p+2∗

vi​,

p+3∗

vi​等,所以我們所有狀態,按照%v

iv_i

vi​的餘數分為等價類。對於每乙個餘數u

uu有狀態轉移方程:

f [u

+p∗v

i]

=max⁡p

−ci≤

k≤p−

1f[u+p*v_i]=\max_\

f[u+p∗

vi​]

=maxp−

ci​≤

k≤p−

1​同理符合上述模型。**不想打了。。。直接看書吧。

回頭學一波斜率優化就ok了。。。。。。。

單調佇列優化動態規劃

lj 那些又遠又差的,我們就不要了 luogup1725 琪露諾 在幻想鄉,琪露諾是以笨蛋聞名的冰之妖精。某一天,琪露諾又在玩速凍青蛙,就是用冰把青蛙瞬間凍起來。但是這只青蛙比以往的要聰明許多,在琪露諾來之前就已經跑到了河的對岸。於是琪露諾決定到河岸去追青蛙。小河可以看作一列格仔依次編號為0到n,琪...

BZOJ1563 詩人小G(1d1d動態規劃)

小g是乙個出色的詩人,經常作詩自娛自樂。但是,他一直被一件事情所困擾,那就是詩的排版問題。一首詩包含了若干個句子,對於一些連續的短句,可以將它們用空格隔開並放在一行中,注意一行中可以放的句子數目是沒有限制的。小g給每首詩定義了乙個行標準長度 行的長度為一行中符號的總個數 他希望排版後每行的長度都和行...

動態規劃之單調佇列優化

先上一道單調佇列動態規劃的模板題 這道題很明顯是一道dp題,可以通過兩個for迴圈就能得到結果,但是n,l,r太大了,兩層for迴圈就超時了,所以我們得用單調佇列來優化。動態規劃一般類如 dp i min dp j f j 0 j i 因為j是從0開始的,使用我們可以用乙個變數記錄dp j f j ...