AcWing 1089. 烽火传递
/*
数组没开够,爆零两行泪
longlong开成int,爆零两行泪
多组忘清空,爆零两行泪
dp 没初值,爆零两行泪
深搜没边界,爆零两行泪
广搜忘出队,爆零两行泪
输入没加 &,爆零两行泪
模数没看见,爆零两行泪
-1 不输出,爆零两行泪
越界不特判,爆零两行泪
线段树开一倍,爆零两行泪
无向变有向,爆零两行泪
题意没审清,爆零两行泪
文件名起错,爆零两行泪
调试忘删除,爆零两行泪
没用freopen,爆零两行泪
*/
#include<bits/stdc++.h>
using namespace std;
const int N=200012;
int n,m;
int q[N];
int f[N];
int w[N];
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>w[i];
int hh=0,tt=0;
// f[0]=0;//边界
for(int i=1;i<=n;i++){
if(q[hh]<i-m) hh++;
f[i]=f[q[hh]]+w[i];
while(hh<=tt&&f[q[tt]]>=f[i]) tt--;
q[++tt]=i;
}
int res=2147483647;
for(int i=n-m+1;i<=n;i++) res=min(res,f[i]);
cout<<res;
return 0;
}
/*
f[i] 表示1~i所有点满足要求,且第i个烽火台被点燃的最小代价
(i-m,i-m+1,i-m+2,...,i-2,i-1)
f[i]=上面这一坨的最小代价 + 点燃第i个烽火台的代价
我们需要求i-m到i-1区间的最小值,考虑用单调队列维护
q[]存的是区间最小代价的下标
*/