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;

}

  

你可能感兴趣的:(poi)