码迷,mamicode.com
首页 > 其他好文 > 详细

JDOJ-1056: 烽火传递

时间:2018-04-26 23:24:07      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:https   include   scanf   span   NPU   status   problems   min   head   

1056: 烽火传递

Time Limit: 1 Sec  Memory Limit: 64 MB
Submit: 209  Solved: 87
[Submit][Status][Web Board]

Description

  烽火台又称烽燧,是重要的军事防御设施,一般建在险要或交通要道上。一旦有敌情发生,白天燃烧柴草,通过浓烟表达信息;夜晚燃烧干柴,以火光传递军情,在某两座城市之间有n个烽火台,每个烽火台发出信号都有一定代价。为了使情报准确地传递,在连续m个烽火台中至少要有一个发出信号。请计算总共最少花费多少代价,才能使敌军来袭之时,情报能在这两座城市之间准确传递。

Input

  第一行:两个整数N,M。其中N表示烽火台的个数,M表示在连续m个烽火台中至少要有一个发出信号。接下来N行,每行一个数Wi,表示第i个烽火台发出信号所需代价。

Output

  一行,表示答案。

Sample Input

5 3 1 2 5 6 2

Sample Output

4

HINT

 

【数据范围】  对于50%的数据,M≤N≤1,000 。  对于100%的数据,M≤N≤ 100,000,Wi≤100。

总结:单调队列优化dp模板
容易想到方程dp[i] = min(dp[j]) (i - m <= j <= i - 1)
然后就单调队列优化
#include<bits/stdc++.h>

using namespace std;
const int maxn = 400005;
#define inf 10000007

int head = 1, n, m, wi[maxn], q[maxn], tail = 1, num[maxn];
long long dp[maxn];
int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) scanf("%d", &wi[i]);
	for (int i = 1; i <= n; ++i) dp[i] = -inf;
	for (int i = 1; i <= n; ++i) {
		dp[i] = dp[num[head]] + wi[i];
		while(head <= tail && dp[i] <= dp[num[tail]]) tail--;
		num[++tail] = i;
		while(num[head] < i + 1 - m)  head++;
	} printf("%lld\n", dp[num[head]]);
	return 0;
}

  

JDOJ-1056: 烽火传递

标签:https   include   scanf   span   NPU   status   problems   min   head   

原文地址:https://www.cnblogs.com/oi-forever/p/8955174.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!