zoukankan      html  css  js  c++  java
  • POJ2823 Sliding Window 单调队列

    这题是给定了一个长度为N的串,问一个固定区域内的最小值和最大值,这题没办法通过DP来求解,因为单纯保留最值的信息是行不通。详见代码:

    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define MAXN 1000005
    using namespace std;
    
    int N, M, seq[MAXN], que[MAXN], front, tail;
    
    /* 
     此题就是要求出给定序列的某一段区间内的最小值和最大值
     一个长为N的序列,每次选取M长的区间进行滑动
     由于框的存在,每个元素有一个存活周期,这里就有一个性质:
     1.每个元素进来时的存活周期为M(框的长度),因为其最多作为M次最优解
     2.每插入一个元素,前面元素的存活周期集体减去1,当一个元素的生存周期为0时,应弃置该元素 
     3.当前插入值的存活周期一定大于以前的元素
     由以上的性质,我们就能够构造一个单调队列,使其满足按照解的优先级排序,如果遇到相同优先级的
     的元素,就按照其生存周期排序,也就是说所有的解的优先级小于等于该元素生存周期小于当前点的元素
     是要进行删除操作,因为当前值足以替代其余值并且拥有更加长的生存周期,所以我们就可以对一个队列
     进行下面的操作,首先找到该号元素的位置,由于当前元素的生存周期最长,所以直接删除其后面的点
     将该元素更新到指定的地方,每次都取出队首元素,做一次生存周期判定,如果不合法,则选取次优的元素
     这个次优的元素也就是生存周期允许的情况下的最优解
    */
    
    int main()
    {
        while (scanf("%d %d", &N, &M) == 2) {
            for (int i = 1; i <= N; ++i) {
                scanf("%d", &seq[i]);
            }
            front = 1, tail = 0;
            for (int i = 1; i < M; ++i) {
                while (front <= tail && seq[i] <= seq[ que[tail] ]) --tail;
                que[++tail] = i; // 保留编号即可,且这样能进行生存周期的判定
            }
            for (int i = M; i <= N; ++i) {
                while (front <= tail && seq[i] <= seq[ que[tail] ]) --tail;
                que[++tail] = i;
                while (que[front] < i-M+1) ++front; // 如果生存周期不合法
                if (i != M) printf(" %d", seq[ que[front] ]);
                else printf("%d", seq[ que[front] ]);
            }
            puts("");
            front = 1, tail = 0;
            for (int i = 1; i < M; ++i) {
                while (front <= tail && seq[i] >= seq[ que[tail] ]) --tail;
                que[++tail] = i;
            }
            for (int i = M; i <= N; ++i) {
                while (front <= tail && seq[i] >= seq[ que[tail] ]) --tail;
                que[++tail] = i;
                while (que[front] < i-M+1) ++front;
                if (i != M) printf(" %d", seq[ que[front] ]);    
                else printf("%d", seq[ que[front] ]);
            }
            puts("");
        }
        return 0;    
    }
  • 相关阅读:
    Asp.net button防止点击多次数据提交
    Asp.net button防止点击多次数据提交
    Asp.net button防止点击多次数据提交
    被投资人坑的大学生创业者
    分析了3200家创业公司
    移动互联网4种引流思维:免费思维、跨界思维、平台思维、金融思维
    腾讯入局、估值超10亿美元,“野路子”瑞幸的三大增长法则
    95后女生月入8万,竟然“玩着玩着”就赚到钱
    95后中介年入百万:“伪焦虑”是你人生最大的骗局
    一家靠收智商税盈利的公司,卖了340亿
  • 原文地址:https://www.cnblogs.com/Lyush/p/2645383.html
Copyright © 2011-2022 走看看