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;    
    }
  • 相关阅读:
    Adobe Flash Player因过期而遭到阻止”的内幕起因和解决办法
    SQL中isnull,nullif,coalesce的用法
    sql server全局变量
    关于分组后字段拼接的问题
    查询某个分组中多行字段值的拼接字串的方法--access
    分组统计(平均值计算)
    excel,sql server,access数据之间相互导入导出
    数据查询和管理
    我为什么学习Windows编程
    zStack学习笔记(原创,绝对不是抄的……)
  • 原文地址:https://www.cnblogs.com/Lyush/p/2645383.html
Copyright © 2011-2022 走看看