BZOJ3831 : [Poi2014]Little Bird
设f[i]表示到i最少休息次数,f[i]=min(f[j]+(h[j]<=a[i])),i-k<=j<i,单调队列优化DP
#include<cstdio> #define N 1000010 inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';} int n,m,i,k,a[N],f[N],h,t,q[N]; inline bool cmp(int x,int y){return f[x]==f[y]?a[x]<a[y]:f[x]>f[y];} int main(){ for(read(n),i=1;i<=n;i++)read(a[i]); for(read(m);m--;printf("%d\n",f[n]))for(read(k),i=h=1,t=0;i<=n;q[++t]=i++){ while(h<=t&&q[h]+k<i)h++; if(i>1)f[i]=f[q[h]]+(a[q[h]]<=a[i]); while(h<=t&&cmp(q[t],i))t--; } return 0; }