zoukankan      html  css  js  c++  java
  • BZOJ3831: [Poi2014]Little Bird

    看上去像是个单调队列

    怎么选出 min{f_j + [h_i >= h_j]} 呢

    只要保证从 f 值最小的里面选出 h 最大的就好了

    由于 h 带来的差异最多是 1,所以可以直接上单调队列

    push 元素的时候比队尾优的条件就是 f[i] < f[tail] 或 (f[i] == f[tail] 且 h[i] >= h[tail])


     代码:

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cctype>
    #include <cstdio>
    #include <queue>
    using namespace std;
    
    const int MAX_N = 1000005;
    
    int n, m, k, hd, tl;
    int h[MAX_N], f[MAX_N], q[MAX_N];
    
    inline int rd() {
    	register int x = 0, c = getchar();
    	while (!isdigit(c)) c = getchar();
    	while (isdigit(c)) {
    		x = x * 10 + (c ^ 48);
    		c = getchar();
    	}
    	return x;
    }
    inline void dp() {
    	hd = 1; tl = 0;
    	f[1] = 0;
    	q[++tl] = 1;
    	for (int i = 2; i <= n; ++i) {
    		while (hd <= tl && i - q[hd] > k) ++hd;
    		f[i] = f[q[hd]] + (h[i] >= h[q[hd]]);
    		while (hd <= tl && ((f[q[tl]] > f[i]) || (f[q[tl]] == f[i] && h[i] >= h[q[tl]]))) --tl;
    		q[++tl] = i;
    	}
    	printf("%d
    ", f[n]);
    }
    
    int main() {
    	n = rd();
    	for (int i = 1; i <= n; ++i) h[i] = rd();
    	m = rd();
    	while (m--) {
    		k = rd();
    		dp();
    	}
    	return 0;
    }
  • 相关阅读:
    第33周二
    第33周一
    第32周日
    第32周六
    RichTextBox 右键显示 ContextMenuTrip
    关于 Head First SQL 中文版
    linux进程通信之共享内存
    chroot 与 jail
    SQL基础--&gt; 约束(CONSTRAINT)
    MessageDigest简单介绍
  • 原文地址:https://www.cnblogs.com/xcysblog/p/9887376.html
Copyright © 2011-2022 走看看