题目描述
有一个长为 n 的序列 a,以及一个大小为 k 的窗口。现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值。
一开始想到的方法是每滑一次,就在这个范围内寻找一次最小值和最大值
但这样很显然会t
所以才会想到单调队列
但是单调队列不会定义一个队列
单调队列是一个数组
存入一个最大值和一个最小值
然后与每次滑到的值进行比较
如果比队尾元素小(大)就放到队尾
如果反之就把队尾元素出队知道符合条件为止
注意队中存入的不是值而是下标
然后就没了
完整代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10;
int n,k;
int q[N],e[N],dp[N];
int head,tail;
int res;
signed main()
{
cin>>n>>k;
for(int i=1;i<=n;i++)
{
cin>>e[i];
e[i]+=e[i-1];
}
for(int i=1;i<=n;i++)
{
while(head<=tail&&q[head]+k<i)
head++;
while(head<=tail&&dp[i-1]-e[i]>=dp[q[tail]-1]-e[q[tail]])
tail--;
dp[i]=max(dp[i-1],dp[q[head]-1]+e[i]-e[q[head]]);
q[++tail]=i;
}
cout<<dp[n];
return 0;
}
封面是本人的洛谷头像,
磷叶石好脆弱我好推