zoukankan      html  css  js  c++  java
  • [codevs3622] 假期(单调队列)

    传送门

    首先考虑暴力做法,可以先求一遍前缀和 sum,然后ans = max(ans, sum[i] - sum[k]) (i - q <= k <= i - p)

    但这个肯定会超时。

    仔细看这个公式,sum[i] 不变,只用求最小 sum[k] 就行,所以可以用单调队列维护这个区间的最小 sum[k]。

    ——代码

     1 #include <cstdio>
     2 #include <iostream>
     3 #define LL long long 
     4 
     5 using namespace std;
     6 
     7 const int MAXN = 100010;
     8 int n, p, q, h = 1, t;
     9 LL a[MAXN], que[MAXN], ans = -0x7fffffff;
    10 
    11 int main()
    12 {
    13     int i, j;
    14     scanf("%d %d %d", &n, &p, &q);
    15     for(i = 1; i <= n; i++)
    16     {
    17         scanf("%lld", &a[i]);
    18         a[i] += a[i - 1];
    19     }
    20     for(i = p; i <= n; i++)
    21     {
    22         while(h <= t && a[que[t]] > a[i - p]) t--;
    23         que[++t] = i - p;
    24         while(h <= t && que[h] < i - q) h++;
    25         ans = max(ans, a[i] - a[que[h]]);
    26     }
    27     printf("%lld", ans);
    28     return 0;
    29 }
    View Code
  • 相关阅读:
    递归与分治4
    递归与分治3
    递归与分治2
    递归与分治1
    枚举与递推3
    枚举与递推2
    求编译器中数的最值(c++)
    移动小球链表实现
    阶乘的精确值
    while((c = getchar()) != EOF)(键盘输入问题)
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/6819540.html
Copyright © 2011-2022 走看看