烽火傳遞
Description
烽火臺又稱烽燧,是重要的防禦設施,一般建在險要處或交通要道上。一旦有敵情發生,白天燃燒柴草,通過濃煙表達信息:夜晚燃燒乾柴,以火光傳遞軍情。在某兩座城市之間有n個烽火臺,每個烽火臺發出信號都有一定的代價。爲了使情報準確的傳遞,在m個烽火臺中至少要有一個發出信號。現輸入n、m和每個烽火臺發出的信號的代價,請計算總共最少需要話費多少代價,才能使敵軍來襲之時,情報能在這兩座城市之間準確的傳遞!!!
Input Format
第一行有兩個數n,m分別表示n個烽火臺,在m個烽火臺中至少要有一個發出信號。
第二行爲n個數,表示每一個烽火臺的代價。
Output Format
一個數,即最小代價。
樣例
5 3
1 2 5 6 2
4
時間限制 Time Limitation
各個測試點1s
註釋 Hint
1<=n,m<=1,000,000
表示被這題坑了快3個多小時了,主要還是DP沒學好啊,最後一個for循環很巧妙,之前想了好久都沒想到這點,還用了兩個單調隊列。。。悲劇阿。。。
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX ((1<<31)-1)
using namespace std;
int value[1000010],Q[1000010],dp[1000010]={0};
int main()
{
int ans=MAX;
int i,n,m,front=0,rear=0;
scanf("%d %d",&n,&m);
for(i=1;i<=n;i++)
{
scanf("%d",&value[i]);
while(front<=rear&&(dp[Q[rear-1]]>dp[i-1]))
rear--;
Q[rear++] = i-1;
while(front<rear&&(i-Q[front])>m)
front++;
dp[i]=dp[Q[front]]+value[i];
}
// for(i=1;i<=n;i++)
// printf("%d\n",dp[i]);
for(i=n;i>=n-m+1;i--)
{
if(ans>dp[i])
ans = dp[i];
}
printf("%d\n",ans);
return 0;
}