1. 程式人生 > >2883 烽火傳遞 動態規劃+單調佇列

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

題目

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

對於50%的資料,M≤N≤1,000 。 對於100%的資料,M≤N≤100,000,Wi≤100。

題解

由於題目要求連續m個烽火臺中至少要有一個發出訊號,很容易得出DP
轉移方程:F[i]=min(F[j]:i−m<j<i)+a[i]
對f[i]的值維護單調佇列,就可以很快地找出最小的f[j]

程式碼

#include <cstdio>
#include <algorithm>

using namespace std;

int n,m,h=1,t,ans=10000010;
int a[100010],f[100010],c[100010];

int main(){
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for (int i=1;i<=n;i++){			
		while ((h<=t)&&(c[i-1]<=c[f[t]])) t--;
		f[++t]=i-1;
		while ((h<=t)&&(f[h]<i-m)) h++;		
		c[i]=a[i]+c[f[h]];		
	}
	for (int i=n-m+1;i<=n;i++)
		if (c[i]<ans) ans=c[i];
	printf("%d\n",ans);
}

此行,只攜,絕勇