《單調佇列》3 烽火傳遞

2021-07-05 13:43:50 字數 1258 閱讀 6765

正如度娘說了:

由於單調佇列的隊頭每次一定最小值,故查詢為o(1)。

進隊出隊稍微複雜點:進隊時,將進隊的元素為e,從隊尾往前掃瞄,直到找到乙個不大於e的元素d,將e放在d之後,捨棄e之後的所有元素;如果沒有找到這樣乙個d,則將e放在隊頭(此時佇列裡只有這乙個元素)。

出隊時,將出隊的元素為e,從隊頭向後掃瞄,直到找到乙個元素f比e後進隊,捨棄f之前所有的。(實際操作中,由於是按序逐個出隊,所以每次只需要出隊只需要比較隊頭)。

每個元素最多進隊一次,出隊一次,攤排分析下來仍然是 o(1)。

單調佇列是一種好東西!o(

1)!

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

其實這道題是一道水題,可以用線段樹,樹狀陣列等方法去做,但實際上單調佇列卻是此題最簡單的做法。 f[

i]=m

in(f

[j]+

1)(j

m)那麼這樣就可以用單調佇列維護mi

n(f[

j])且

(jm)

的值。

while ((l<=r)&&(g[l]f[i])) r--;\\用當前的f[i]去更新隊尾,使佇列保持單調性

g[++r]=i; \\進隊

#include

#include

#include

#include

#include

#include

#define fo(i,a,b) for(int i=a;i<=b;i++)

#define fd(i,a,b) for(int i=a;i>=b;i--)

using

namespace

std;

const

int n=100005;

int m,n,i,f[n],a[n],g[n],l,r,an;

int main()an=2147483647;

fo(i,n-m+1,n) an=min(an,f[i]);

printf("%d",an);

}

烽火傳遞 單調佇列

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

烽火傳遞 單調佇列 DP

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

單調佇列優化DP 烽火傳遞

烽火台是重要的軍事防禦設施,一般建在交通要道或險要處。一旦有軍情發生,則白天用濃煙,晚上有火光傳遞軍情。在某兩個城市之間有 n 座烽火台,每個烽火台發出訊號都有一定的代價。為了使情報準確傳遞,在連續 m 個烽火台中至少要有乙個發出訊號。現在輸入 n,m 和每個烽火台的代價,請計算在兩城市之間準確傳遞...