//要熟练手写队列
//单调队列优化DP筛选转移点
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1000010;
int n, qut;
int q[maxn], f[maxn], h[maxn];
inline void getInit(){
memset(f, 0, sizeof(f));
memset(q, 0, sizeof(q));
}
inline bool judge(int x, int y){//单调队列优先级,先f因为若f[i]<f[j],最不济也可以调到j上,然后比h,同样h[i]>=h[j]时可以无伤跳到j上
if(f[x] != f[q[y]]) return f[x] < f[q[y]];
return h[x] >= h[q[y]];
}
int main(){
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%d", &h[i]);
scanf("%d", &qut);
while(qut--){
getInit();
int k;
scanf("%d", &k);
f[1] = 0;
int front = 0, tail = 0;
q[0] = 1;
for(int i = 2; i <= n; i++){
while(front <= tail && i - q[front] > k) front++;
f[i] = f[q[front]] + (h[q[front]] <= h[i]);
while(front <= tail && judge(i, tail-1)) tail--;
q[++tail] = i;//tail是指向最后一个元素的后一个,所以
}
printf("%d\n", f[n]);
}
return 0;
}
BZOJ 3831 Little Bird
最新推荐文章于 2018-01-30 22:40:59 发布