zoukankan      html  css  js  c++  java
  • 单调队列 笔记

    很早看过这个东西,不过今天遇到一道题发现居然没有写笔记。。。这里补上吧。

    以下是我从某个题的解题报告翻出来的。转载的别人的。。。。

    以此为例:对于N=8,K=3,8个元素序列1 3 -1 -3 5 3 6 7,窗口大小为3,也就是要求出(1, 3, -1), (3, -1, -3), (-1, -3, 5), (-3, 5, 3), (5, 3, 6), (3, 6, 7)这6个序列中的最小值,结果简单,就是-1, -3, -3, -3, 3, 3. 

    使用单调队列,首先要有一个数据结构

    struct node { int seq, val; }

    用于记录队列中的元素及其在输入序列中的顺序。队列的状态是这样维护的:

    1: [0,  1] //队列空,[seq=0, val=1]入队
    3: [0,  1], [1,  3] //3大于队尾元素,放在队尾
    -1: [2, -1] //从队尾往前扫,-1小于每一个所有元素,于是把它们都T掉
    -3: [3, -3] //-3把-1T掉
    5: [3, -3], [4,  5] //入队尾
    3: [3, -3], [5,  3] //把队尾的5T掉
    6:            [5,  3], [6,  6] //队首元素seq=3太老了,T掉;6比3小,放在队尾
    7: [5,  3], [6,  6], [7,  7] //入队尾

    从以上的处理方法可以看出:最老的元素要么早就被T掉了,要么就是最小的元素(排在队首)。所以每次加入一个新元素的时候:
    1. 把需要出队的队首元素T掉;
    2. 把队尾大于或等于它的元素全部T掉,自己入队。

     

    说白了就是是保证窗口的元素的value是从前往后是依次减小(增大)的。还有一个值就是当前value的position,也就是说窗口里所有元素 的position都必须跟当前待插入的元素的position的距离相差小于等于窗口的大小。(-_-! 说的好别扭)

     

    今天补补模板吧。。。。

    class Node {
    public:
        int pos;
        int val;
        Node() {};
        Node(int _a, int _b) : pos(_a), val(_b) {}
    };
    
    class Dequ{
        Node deq[N];
    public:
        void Get_Min(int ans[], int _num[], int n, int k) {
            int i, head, tail;
            head = tail = 0;
            REP(i, n) {
                if(head < tail && deq[head].pos <= i - k)   head++;
                while(head < tail && deq[tail-1].val >= _num[i])    tail--;
    
                deq[tail++] = Node(i, _num[i]);
                ans[i] = deq[head].val;
            }
        }
        void Get_Max(int ans[], int _num[], int n, int k) {
            int i, head, tail;
            head = tail = 0;
            REP(i, n) {
                if(head < tail && deq[head].pos <= i - k)   head++;
                while(head < tail && deq[tail-1].val <= _num[i])    tail--;
    
                deq[tail++] = Node(i, _num[i]);
                ans[i] = deq[head].val;
            }
        }
    } Dequeue;

     

  • 相关阅读:
    祝好,又十年
    关于简书的吐槽与思考还有杂七杂八负面情绪宣泄
    康威生命游戏———孤独会致命,拥挤也一样(转载)
    Bran的内核开发教程(bkerndev)-07 中断描述符表(IDT)
    Ubuntu安装QQ
    Bran的内核开发教程(bkerndev)-06 全局描述符表(GDT)
    Ubuntu安装scrcpy手机投屏和控制(Ubuntu用QQ微信的另一种方法)
    C、C++的Makefile模板
    C语言打印当前所在函数名、文件名、行号
    Bran的内核开发教程(bkerndev)-05 打印到屏幕
  • 原文地址:https://www.cnblogs.com/vongang/p/2608436.html
Copyright © 2011-2022 走看看