有一排n棵树,第i棵树的高度是Di。
MHY要从第一棵树到第n棵树去找他的妹子玩。
如果MHY在第i棵树,那么他可以跳到第i+1,i+2,...,i+k棵树。
如果MHY跳到一棵不矮于当前树的树,那么他的劳累值会+1,否则不会。
为了有体力和妹子玩,MHY要最小化劳累值。
标签:win pac cond nbsp bool tput 单调队列 r++ ecif
BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP
首先有DP方程F[i]=min(F[j]+(d[i]>=d[j])) (1<=i-j<=k)
可以发现作为决策点,F值小的更优(因为每次最多只加1),F值相同的高的更优。
于是可以用单调队列优化DP过程。
比较决策点谁更优时先比较F,再比较高度。
代码:
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define N 1000500 int f[N],d[N],n,m,Q[N],l,r; bool check(int j,int k) { if(f[j]==f[k]) return d[k]>d[j]; return f[k]<f[j]; } int main() { scanf("%d",&n); int i,k; for(i=1;i<=n;i++) { scanf("%d",&d[i]); } scanf("%d",&m); while(m--) { scanf("%d",&k); l=r=0; f[1]=0;Q[r++]=1; for(i=2;i<=n;i++) { while(l<r&&i-Q[l]>k) l++; f[i]=f[Q[l]]+(d[i]>=d[Q[l]]); while(l<r&&check(Q[r-1],i)) r--; Q[r++]=i; } printf("%d\n",f[n]); } }
BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP
标签:win pac cond nbsp bool tput 单调队列 r++ ecif
原文地址:https://www.cnblogs.com/suika/p/8998037.html