f[i]表示从1走到i的最小劳累值
因为高度的影响至多增加1的花费,可以用单调队列,按f从小到大维护,对于f相同的优先保留高度大的
code:
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
inline void read(int &x)
{
char c;while(!((c=getchar())>='0'&&c<='9'));
x=c-'0';
while((c=getchar())>='0'&&c<='9') (x*=10)+=c-'0';
}
const int maxn = 1100000;
int n,m,K;
int a[maxn],f[maxn];
int q[maxn],head,tail;
int main()
{
read(n);
for(int i=1;i<=n;i++) read(a[i]);
read(m);
while(m--)
{
int K; read(K);
f[1]=0; q[head=tail=1]=1;
for(int i=2;i<=n;i++)
{
while(i-q[head]>K) head++;
f[i]=f[q[head]]+(a[q[head]]<=a[i]?1:0);
while(head<=tail&&(f[q[tail]]>f[i]||(f[q[tail]]==f[i]&&a[q[tail]]<=a[i]))) tail--;
q[++tail]=i;
}
printf("%d\n",f[n]);
}
return 0;
}