思路:
设 f i f_i fi表示到第i个人要用的最小花费,然后从前k个转移过来,用单调队列来维护
c o d e code code
#include<iostream>
#include<cstdio>
using namespace std;
int n, t;
int a[1000100], f[1000100];
int q[1000100];
int main()
{
scanf("%d", &n);
for(int i=1; i<=n; i++)
scanf("%d", &a[i]);
scanf("%d", &t);
while(t--)
{
int k;
scanf("%d", &k);
int tl=1, hd=1;
f[1]=0, q[1]=1;
for(int i=2; i<=n; i++)
{
while(hd<=tl&&q[hd]<i-k)
hd++;
if(a[q[hd]]>a[i])
f[i]=f[q[hd]];
else
f[i]=f[q[hd]]+1;
while(hd<=tl&&((f[i]==f[q[tl]]&&a[i]>=a[q[tl]])||(f[i]<f[q[tl]])))
tl--;
q[++tl]=i;
}
printf("%d\n", f[n]);
}
return 0;
}