烽火台又稱烽燧,是重要的軍事防禦設施,一般建在險要或交通要道上。一旦有敵情發生,白天燃燒柴草,通過濃煙表達資訊;夜晚燃燒乾柴,以火光傳遞軍情,在某兩座城市之間有 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,從隊頭向後掃瞄...