最近經常出現單調佇列,斜率優化的題目。看到周圍的大神們都會做了,我只能跟上去。
要慢慢來,先學單調佇列。
類似這樣的轉移方程可以用到單調佇列: f[
i]=m
ax(g
[j])
+w[i
] 其中,g[j]是乙個與i無關係的數。w[i]只與i有關係。
我們首先開乙個佇列。dp時:
1、先刪掉前面超出範圍的隊頭。
2、利用隊頭轉移。
3、將這個數和隊尾比較,若隊尾不比它優,就刪掉隊尾,直到隊列為空或隊尾比它優。最後將它加進隊尾。
1、單調佇列中的數都在要範圍之內。
2、隊頭最優(不然早被後面的刪掉了)。
3、為什麼不只存隊頭?因為隊頭比較老,若超出範圍就要被刪掉。
description在單調佇列的題中,這是一道水題了。烽火台又稱烽燧,是重要的軍事防禦設施,一般建在險要或交通要道上。一旦有敵情發生,白天燃燒柴草,通過濃煙表達資訊;夜晚燃燒乾柴,以火光傳遞軍情,在某兩座城市之間有n個烽火台,每個烽火台發出訊號都有一定代價。為了使情報準確地傳遞,在連續m個烽火台中至少要有乙個發出訊號。請計算總共最少花費多少代價,才能使敵軍來襲之時,情報能在這兩座城市之間準確傳遞。
input
第一行:兩個整數n,m。其中n表示烽火台的個數,m表示在連續m個烽火台中至少要有乙個發出訊號。接下來n行,每行乙個數wi,表示第i個烽火台發出訊號所需代價。
output
一行,表示答案。
sample input
5 3
1 2
5 6
2sample output
4data constraint
對於50%的資料,m≤n≤1,000 。 對於100%的資料,m≤n≤ 100,000,wi≤100。
設f[i]表示i必須選時最小代價。
初值:
f[0]=0 f[1..n]=∞
方程:
f[i]=min(f[j])+w[i]
並且max(0,i-m)<=j沒有單調佇列的**
#include
#include
#include
using
namespace
std;
#define i_o(x) freopen(""#x".in","r",stdin);freopen(""#x".out","w",stdout)
int n,m;
int w[100001];
int f[100001];
int main()
for (i=m;i<=n;++i)
我們發現這個方程可以以單調佇列實現,用單調佇列存好最優決策點,就可以將時間複雜度從o(nm)降到o(n)。
正解**
#include
#include
#include
using
namespace
std;
#define i_o(x) freopen(""#x".in","r",stdin);freopen(""#x".out","w",stdout)
int n,m;
int w[100001];
int que[100001],head=0,tail=0;
int f[100001];
int main()
int ans=0x7f7f7f7f;
for (i=n-m+1;i<=n;++i)
ans=min(ans,f[i]);
printf("%d\n",ans);
}
單調佇列優化動態規劃
lj 那些又遠又差的,我們就不要了 luogup1725 琪露諾 在幻想鄉,琪露諾是以笨蛋聞名的冰之妖精。某一天,琪露諾又在玩速凍青蛙,就是用冰把青蛙瞬間凍起來。但是這只青蛙比以往的要聰明許多,在琪露諾來之前就已經跑到了河的對岸。於是琪露諾決定到河岸去追青蛙。小河可以看作一列格仔依次編號為0到n,琪...
動態規劃之單調佇列優化
先上一道單調佇列動態規劃的模板題 這道題很明顯是一道dp題,可以通過兩個for迴圈就能得到結果,但是n,l,r太大了,兩層for迴圈就超時了,所以我們得用單調佇列來優化。動態規劃一般類如 dp i min dp j f j 0 j i 因為j是從0開始的,使用我們可以用乙個變數記錄dp j f j ...
hdu 3401 單調佇列優化動態規劃
思路 動態方程很容易想到dp i j max dp i j dp i w 1 j k k ap i dp i w 1 j k k bp i dp i j 表示第i天擁有j個石頭的最大價值。其實每次求得都是最有策略,所有dp i w 1 表示的就是i w 1以前的最優,故不同往前遍歷。那麼主要需要優化...