烽火传递(单调队列优化dp,然而蒟蒻用一个优先队列做)

题目

烽火台是重要的军事防御设施,一般建在交通要道或险要处。一旦有军情发生,则白天用浓烟,晚上有火光传递军情。
在某两个城市之间有 n 座烽火台,每个烽火台发出信号都有一定的代价。为了使情报准确传递,在连续 m 个烽火台中至少要有一个发出信号。现在输入 n,m 和每个烽火台的代价,请计算总共最少的代价在两城市之间来准确传递情报。
输入
第一行是 n,m ,表示 n 个烽火台和连续烽火台数 m ;
第二行 n 个整数表示每个烽火台的代价 ai
输出
输出仅一个整数,表示最小代价。
样例输入 [复制]
5 3
1 2 5 6 2
样例输出 [复制]
4
提示
在第 2,5 号烽火台上发信号。
对于全部数据,1≤n,m≤2×10^5,1≤ai≤1000

很简单的单调队列啊,然后随手写了一个优先队列,反正都是一样的,虽然要慢一点,反正问题不大

#include<bits/stdc++.h>
using namespace std;
struct node{int a,b;};
priority_queue<node> q;
int a[200005],n,m,dp[200005];
bool c[200005];
inline int read(){
    	char ch=getchar();
    	int res=0;
    	while(!isdigit(ch)) ch=getchar();
    	while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
    	return res;
}
inline bool operator<(node A,node B){return A.a>B.a;}
int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)
    	{
    		    scanf("%d",&a[i]);
    	}
    	for(int i=1;i<=m;i++)
    	{
    	    	dp[i]=a[i];
	        	q.push((node){a[i],i});
    	}
    	for(int i=m+1;i<=n;i++)
	    {
    	    	while(c[q.top().b])
    	    	q.pop();
    	    	dp[i]=q.top().a+a[i];
    		    c[i-m]=true;
	        	q.push((node){dp[i],i});
    	}
    	int ans=99999999;
    	for(int i=n-m+1;i<=n;i++)
    	{
    	    	ans=min(ans,dp[i]);
    	}
    	cout<<ans<<endl;
    	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42555009/article/details/82807492
今日推荐