BZOJ3831 : [Poi2014]Little Bird

Claris發表於2015-01-05

設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;
}

  

相關文章