ssl2883 烽火傳遞 單調佇列優化 DP

2021-10-09 01:20:40 字數 1699 閱讀 3627

烽火台又稱烽燧,是重要的軍事防禦設施,一般建在險要或交通要道上。一旦有敵情發生,白天燃燒柴草,通過濃煙表達資訊;夜晚燃燒乾柴,以火光傳遞軍情,在某兩座城市之間有 n 個烽火台,每個烽火台發出訊號都有一定代價。為了使情報準確地傳遞,在連續 m 個烽火台中至少要有乙個發出訊號。請計算總共最少花費多少代價,才能使敵軍來襲之時,情報能在這兩座城市之間準確傳遞。

第一行:兩個整數 n,m。其中n表示烽火台的個數, m 表示在連續 m 個烽火台中至少要有乙個發出訊號。接下來 n 行,每行乙個數 wi,表示第i個烽火台發出訊號所需代價。

一行,表示答案。

531

2562

4
hint

對於50%的資料,m≤n≤1,000 。 對於100%的資料,m≤n≤100,000,wi≤100。

這題本質上是乙個dp。很容易得出狀態轉移方程:f[i

]=mi

n(f[

j]:i

−m<

j+a[i

]f[i]=min(f[j]:i-mf[

i]=m

in(f

[j]:

i−m<

j+a[i

]但是直接這樣的話時間複雜度就是o(n

∗n)o(n*n)

o(n∗n)

下面講一下單調佇列優化的具體做法。

上圖中,狀態列舉到i,當m=4時,我們要做的就是在i-3到i-1中找到最小的f[j],那麼列舉到i+1時,我們要做的就是要在i-2到i中找到最小的f[j]。上圖中我們可以看出,要尋找最小值的區間向後移動了一位,也就是f[i-m+1]的值被拋棄,f[i-1]的值被加入。這裡就可以用單調佇列處理了,f[i-1]是插隊的資料,f[i-1]有資格插隊是因為它更優且更靠近i,比它更差的數將被它取代,保留那些資料沒有任何好處。而那些已經不再維護區間之外的就不必再對其進行維護,出隊即可。

跟模板差不多,只是加上狀態轉移和統計就完事。

#include

#include

#include

#include

#include

using

namespace std;

int n,m,h,t,a[

100001

],q[

1000001

],f[

100001];

intmain()

h=0;t=1

;for

(int i=

1;i<=n;i++

) t++

; q[t]

=i-1

;//把f[i-1]插入,這裡插入下標而不插入值,便於從隊頭彈出

while

(h<=t&&q[h]

//已經不屬於區間維護內的數彈出

f[i]

=f[q[h]

]+a[i]

;//狀態轉移方程

}int ans;

for(

int i=n;i>=n-m+

1;i--

)//統計

cout<

return0;

}

2883 烽火傳遞 動態規劃 單調佇列

烽火台又稱烽燧,是重要的軍事防禦設施,一般建在險要或交通要道上。一旦有敵情發生,白天燃燒柴草,通過濃煙表達資訊 夜晚燃燒乾柴,以火光傳遞軍情,在某兩座城市之間有 n 個烽火台,每個烽火台發出訊號都有一定代價。為了使情報準確地傳遞,在連續 m 個烽火台中至少要有乙個發出訊號。請計算總共最少花費多少代價...

烽火傳遞 單調佇列

烽火台又稱烽燧,是重要的軍事防禦設施,一般建在險要或交通要道上。一旦有敵情發生,白天燃燒柴草,通過濃煙表達資訊 夜晚燃燒乾柴,以火光傳遞軍情,在某兩座城市之間有n個烽火台,每個烽火台發出訊號都有一定代價。為了使情報準確地傳遞,在連續m個烽火台中至少要有乙個發出訊號。請計算總共最少花費多少代價,才能使...

《單調佇列》3 烽火傳遞

正如度娘說了 由於單調佇列的隊頭每次一定最小值,故查詢為o 1 進隊出隊稍微複雜點 進隊時,將進隊的元素為e,從隊尾往前掃瞄,直到找到乙個不大於e的元素d,將e放在d之後,捨棄e之後的所有元素 如果沒有找到這樣乙個d,則將e放在隊頭 此時佇列裡只有這乙個元素 出隊時,將出隊的元素為e,從隊頭向後掃瞄...