bzoj 3831 Little Bird (单调队列优化dp)
/*先贴个n*n的*/ #include<iostream> #include<cstdio> #include<cstring> #define maxn 1000010 using namespace std; int n,k,h[maxn],f[maxn],Q; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&h[i]); scanf("%d",&Q); while(Q--) { scanf("%d",&k); memset(f,127/3,sizeof(f)); f[1]=0; for(int i=1;i<=n;i++) for(int j=i-k;j<i;j++) { if(j<=0)continue; if(h[i]>=h[j])f[i]=min(f[i],f[j]+1); if(h[i]<h[j])f[i]=min(f[i],f[j]); } printf("%d\n",f[n]); } return 0; }
/* 对于每次的查找最小值 用单调队列维护 */ #include<iostream> #include<cstdio> #include<cstring> #define maxn 1000010 using namespace std; int n,k,h[maxn],f[maxn],Q,q[maxn],head,tail; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&h[i]); scanf("%d",&Q); while(Q--) { head=1;tail=0; scanf("%d",&k); f[1]=0;q[++tail]=1; for(int i=2;i<=n;i++) { while(tail>=head&&i-q[head]>k)head++; if(h[i]>=h[q[head]])f[i]=f[q[head]]+1; else f[i]=f[q[head]]; while(head<=tail&&f[i]<=f[q[tail]]) { if(f[i]==f[q[tail]]&&h[i]<h[q[tail]])break; tail--; } q[++tail]=i; } printf("%d\n",f[n]); } return 0; }