其他分享
首页 > 其他分享> > 考试7.15

考试7.15

作者:互联网

烽火传递(signal.cpp)

【题目描述】
烽火台是重要的军事防御设施,一般建在交通要道或险要处。一旦有军情发
生,则白天用浓烟,晚上用火光传递军情。
在某两个城市之间有n座烽火台,每个烽火台发出信号都有一定的代价。为
了使情报准确传递,在连续m个烽火台中至少要有一个发出信号。
现在输入n和每个烽火台发出信号的代价ai,请计算总共最少需多少的代价
才能实现两城市之间准确传递情报。
【输入格式】
第一行是用空格隔开两个数 n 和 m;
第二行使用空格隔开的 n 个整数,表示每个烽火台发出信号的代价。
【输出格式】
输出仅一个整数,表示最小代价。


单调优先队列优化dp

错误原因:弹出队尾时f[i]打成f[q[i]]

代码

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,m;
int a[N],q[N],f[N];//以i为结尾的最小

inline int read() {
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9') {
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9') {
		x=x*10+ch-'0';
		ch=getchar();
	}
	return x*f;
}

int main() {
//	freopen("signal.in","r",stdin);
//	freopen("signal.out","w",stdout);
	n=read(),m=read();
	for(int i=1; i<=n; i++) {
		a[i]=read();
	}
	memset(f,0x3f,sizeof f);
	int l=1,r=1;
	f[0]=0;
	for(int i=1; i<=n; i++) {
		while(l<r&&q[l]+m<i)l++;
		f[i]=f[q[l]]+a[i];
// cout<<l<<" "<<r<<" "<<i<<" :"<<f[i]<<endl;
		while(l<r&&f[q[r]]>f[i])r--;
		q[++r]=i;
	}
	int ans=0x3f3f3f3f;
	for(int i=n-m+1; i<=n; i++) {
// cout<<i<<" "<<f[i]<<endl;
		ans=min(ans,f[i]);
	}
	cout<<ans<<endl;
	return 0;
}

标签:7.15,ch,烽火台,int,while,代价,发出信号,考试
来源: https://www.cnblogs.com/mkik/p/16482587.html