SSLOJ2883 烽火传递

Description

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

Input

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

Output

一行,表示答案。

思路

方程: F [ i ] = m i n ( F [ j ] ) + a [ i ] ( i − m < j < i ) F[i]=min(F[j])+a[i](i-m<j<i) F[i]=min(F[j])+a[i](im<j<i)
min的部分用单调队列完成。
code:

#include<iostream>
#include<cstdio>
#include<deque>
using namespace std;
long long n,m,s[100001],f[100001],x,mx=2147483647;
deque<int> o;
int main()
{
    
    
 cin>>n>>m;
 for (int i=1;i<=n;i++)
 {
    
    
  cin>>s[i];
 }
 for (int i=1;i<=n;i++)
 {
    
    
  while (o.size()&&f[o.back()]>=f[i-1]) o.pop_back();
  o.push_back(i-1);
  while (o.size()&&o.front()<i-m)
  {
    
    
   o.pop_front();
  }
  f[i]=f[o.front()]+s[i];
  if (i>=n-m+1) mx=min(mx,f[i]);
 }
 cout<<mx;
 return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_49843717/article/details/113954022