列表

详情


NC50533. 烽火传递

描述

烽火台是重要的军事防御设施,一般建在交通要道或险要处。一旦有军情发生,则白天用浓烟,晚上有火光传递军情。
在某两个城市之间有n座烽火台,每个烽火台发出信号都有一定的代价。为了使情报准确传递,在连续m个烽火台中至少要有一个发出信号。现在输入n,m和每个烽火台的代价,请计算总共最少的代价在两城市之间来准确传递情报。

输入描述

第一行是n,m,表示n个烽火台和连续烽火台数m;
第二行n个整数表示每个烽火台的代价a_i

输出描述

输出仅一个整数,表示最小代价。

示例1

输入:

5 3
1 2 5 6 2

输出:

4

说明:

在第2,5号烽火台上发信号。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

Python3 解法, 执行用时: 257ms, 内存消耗: 30252K, 提交时间: 2023-04-29 15:15:51

import sys

f = [0] * 200010 
q = [0] * 200010

n, m = map(int, sys.stdin.readline().split())
w = list(map(int, sys.stdin.readline().split()))
w.insert(0, 0)

hh = 0
tt = 0
f[0] = 0
for i in range(1, n + 1):
    if q[hh] < i - m:
        hh += 1
    f[i] = f[q[hh]] + w[i]
    while hh <= tt and f[q[tt]] >= f[i]:
        tt -= 1
    tt += 1
    q[tt] = i
res = 1e9
for i in range(n - m + 1, n + 1):
    res = min(res, f[i])

print(res)

C++ 解法, 执行用时: 36ms, 内存消耗: 1912K, 提交时间: 2021-11-14 15:02:16

#include<bits/stdc++.h>
using namespace std;
int a[200001],f[200001],q[200001];
int main(){
	int n,m,l = 1,r = 1,i;
	cin>>n>>m;
	for (i = 1;i <= n;i++)
		cin>>a[i];
	for (i = 1;i <= n;i++){
		while (l <= r && i - q[l] > m)
			l++;
		f[i] = f[q[l]] + a[i];
		while (l <= r && f[q[r]] > f[i])
			r--;
		q[++r] = i;
	}
	int ans = f[n];
	for (i = n - m + 1;i < n;i++)
		if (f[i] < ans)ans = f[i];
	cout<<ans;
	return 0;
}

上一题