[POI 2014]Little Bird(单调队列优化DP)
2015-05-13 11:39
309 查看
题目链接
http://main.edu.pl/en/archive/oi/21/pta题目大意
mm只小鸟各自要从1号柱子飞到nn号柱子,假如当前小鸟在ii号柱子,那么它可以飞向i+1i+1到i+Kii+K_i号柱子,若小鸟从柱子ii飞到了柱子jj且Hi≤HjH_i \leq H_j,则小鸟需要付出1单位的代价,问每只小鸟从柱子1飞到柱子nn各自至少需要花费多少代价。思路
用f[i]f[i]表示小鸟飞到柱子ii的代价,容易推出DP方程f[i]=min{f[j]},i−K≤j≤i−1且Hj>Hif[i]=\min \{ f[j]\},i-K\leq j \leq i-1且H_j>H_i
f[i]=min{f[j]+1},i−K≤j≤i−1且Hj≤Hif[i]=\min \{ f[j]+1\},i-K\leq j \leq i-1且H_j\leq H_i
这个DP可以通过单调队列优化,在单调队列里,对于队列中位置i,ji,j的元素,且i<ji而言,有f[i]<f[j]f[i]或f[i]=f[j]f[i]=f[j]且Hi>HjH_i>H_j。这样就能保证每次取出队首元素是最优的。
吐槽一句:此题样例真是太水了,蒟蒻忘了每次DP后在队尾入队,还过了样例。。。
代码
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <algorithm> #define MAXN 1100000 using namespace std; int n,m,H[MAXN],f[MAXN],q[MAXN]; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&H[i]); scanf("%d",&m); while(m--) { int K; scanf("%d",&K); int h=0,t=0; for(int i=0;i<=n;i++) f[i]=0; q[t++]=1; for(int i=2;i<=n;i++) { while(h<t&&q[h]+K<i) h++; f[i]=f[q[h]]+(H[q[h]]<=H[i]?1:0); while(h<t&&(f[q[t-1]]>f[i]||(f[q[t-1]]==f[i]&&H[q[t-1]]<=H[i]))) t--; q[t++]=i; //!!!!!哇靠我SB了 } printf("%d\n",f ); } return 0; }
相关文章推荐
- bzoj3831 [Poi2014]Little Bird(单调队列优化dp)
- bzoj3831 [Poi2014]Little Bird 单调队列优化dp
- BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP
- 【bzoj3831】[Poi2014]Little Bird(单调队列优化dp)
- BZOJ 3831 [Poi2014]Little Bird【单调队列优化dp
- 【bzoj3831】[Poi2014]Little Bird 单调队列优化dp
- 【BZOJ】【P3831】【Poi2014】【Little Bird】【题解】【单调队列+DP】
- BZOJ 3831 POI 2014 Little Bird 单调队列DP
- 3831: [Poi2014]Little Bird|DP|单调队列
- 【BZOJ3831】【POI2014】Little Bird 单调队列,''再不刷它就土了''系列。
- 【BZOJ3831】[Poi2014]Little Bird 单调队列
- bzoj 3831 Little Bird (单调队列优化dp)
- 【GDOI2014模拟】服务器 (斜率单调队列优化Dp)
- 2014 Super Training #2 C Robotruck --单调队列优化DP
- [luoguP3572] [POI2014]PTA-Little Bird(DP + 单调队列)
- bzoj3831 洛谷3572 little bird 单调队列优化dp
- 【单调队列】【动态规划】bzoj3831 [Poi2014]Little Bird
- 数组与STL实现单调队列的区别 POI2014 PTA-Little Bird
- 【BZOJ3831】Little Bird,单调队列优化DP
- BZOJ 1855 股票交易(单调队列优化DP)