【BZOJ】【3831】【POI2014】Little Bird
DP/单调队列优化
水题水题水题水题
单调队列优化的线性dp……
WA了8次QAQ,就因为我写队列是[l,r),但是实际操作取队尾元素的时候忘记了……不怎么从队尾取元素嘛……平时都是直接往进放的……还是得记住这个双端队列的错点啊!!
1 //BZOJ 3831 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<iostream> 6 #include<algorithm> 7 #define rep(i,n) for(int i=0;i<n;++i) 8 #define F(i,j,n) for(int i=j;i<=n;++i) 9 #define D(i,j,n) for(int i=j;i>=n;--i) 10 using namespace std; 11 const int N=1000086,INF=~0u>>2; 12 //#define debug 13 int n,m,a[N],f[N],q[N]; 14 15 int main(){ 16 #ifndef ONLINE_JUDGE 17 freopen("file.in","r",stdin); 18 #endif 19 scanf("%d",&n); 20 F(i,1,n) scanf("%d",&a[i]); 21 22 scanf("%d",&m); 23 while(m--){ 24 int l=0,r=0,k=0; 25 memset(q,0,sizeof q); 26 27 scanf("%d",&k); 28 f[0]=f[1]=0; 29 q[r++]=1; 30 F(i,2,n){ 31 while(q[l]+k<i && l<r) l++; 32 f[i]=f[q[l]] + ((a[q[l]]<=a[i]) ? 1 : 0) ; 33 while( ((f[i]<f[q[r-1]]) || (f[i]==f[q[r-1]] && a[i]>=a[q[r-1]])) && l<r) r--; 34 q[r++]=i; 35 } 36 printf("%d\n",f[n]); 37 } 38 return 0; 39 }
3831: [Poi2014]Little Bird
Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 191 Solved: 114
[Submit][Status][Discuss]
Description
In
the Byteotian Line Forest there are trees in a row. On top of the
first one, there is a little bird who would like to fly over to the top
of the last tree. Being in fact very little, the bird might lack the
strength to fly there without any stop. If the bird is sitting on top of
the tree no. , then in a single flight leg it can fly to any of the
trees no.i+1,i+2…I+K, and then has to rest afterward.
Moreover, flying up is far harder to flying down. A flight leg is
tiresome if it ends in a tree at least as high as the one where is
started. Otherwise the flight leg is not tiresome.
The goal is to select the trees on which the little bird will land
so that the overall flight is least tiresome, i.e., it has the minimum
number of tiresome legs. We note that birds are social creatures, and
our bird has a few bird-friends who would also like to get from the
first tree to the last one. The stamina of all the birds varies, so the
bird's friends may have different values of the parameter . Help all
the birds, little and big!
有一排n棵树,第i棵树的高度是Di。
MHY要从第一棵树到第n棵树去找他的妹子玩。
如果MHY在第i棵树,那么他可以跳到第i+1,i+2,...,i+k棵树。
如果MHY跳到一棵不矮于当前树的树,那么他的劳累值会+1,否则不会。
为了有体力和妹子玩,MHY要最小化劳累值。
Input
There is a single
integer N(2<=N<=1 000 000) in the first line of the standard
input: the number of trees in the Byteotian Line Forest. The second line
of input holds integers D1,D2…Dn(1<=Di<=10^9) separated by
single spaces: Di is the height of the i-th tree.
The third line of the input holds a single integer
Q(1<=Q<=25): the number of birds whose flights need to be planned.
The following Q lines describe these birds: in the i-th of these lines,
there is an integer Ki(1<=Ki<=N-1) specifying the i-th bird's
stamina. In other words, the maximum number of trees that the i-th bird
can pass before it has to rest is Ki-1.
Output
Your program
should print exactly Q lines to the standard output. In the I-th line,
it should specify the minimum number of tiresome flight legs of the i-th
bird.
Sample Input
9
4 6 3 6 3 7 2 6 5
2
2
5
4 6 3 6 3 7 2 6 5
2
2
5
Sample Output
2
1
1
HINT
Explanation: The first bird may stop at the trees no. 1, 3, 5, 7, 8, 9. Its tiresome flight legs will be the one from the 3-rd tree to the 5-th one and from the 7-th to the 8-th.