zoukankan      html  css  js  c++  java
  • 一本通 最大连续和

    写下单调队列思路怕自己忘

    计算区间和的问题,一般转换为两个前缀和相减,所以我们先求出前缀和sum[i]表示前i项的和,那么就转化成了求 $s[r]-s[l-1]$

    枚举右端点,则问题变为:找到一个左端点, $im<=j<=i1$ 且 $s[j]$ 最小

    然后执行单调队列的几个步骤:

    1. 判断队首与i的距离是否超过M的范围,若超出则弹

    2. 更新答案,因为此时队首就是右端点为i时,左端点j最佳选择

    3. 不断删除队尾,直到队尾的sum小于sum[i],然后将i入队

      #include <iostream>
      #include <cstdio>
      #include <algorithm>
      #include <cstring>
      #define re register int
      #define ll long long
      #define maxn 300005
      using namespace std;
      int a[maxn], q[maxn], sum[maxn];
      int l, r;
      int n, m;
      int main() {
          scanf("%d%d", &n, &m);
          for (re i = 1; i <= n; i++) scanf("%d", &a[i]), sum[i] = sum[i - 1] + a[i];
          l = 1, r = 1;
          q[1] = 0;
          int ans = -0x3f3f3f3f;
          for (re i = 1; i <= n; i++) {
              while (l <= r && q[l] < i - m) l++;
              ans = max(ans, sum[i] - sum[q[l]]);
              while (l <= r && sum[q[r]] >= sum[i]) r--;
              q[++r] = i;
          }
          printf("%d
      ", ans);
          return 0;
      }
    缘分让我们相遇乱世以外, 命运却要我们危难中相爱。 也许未来遥远在光年之外, 我愿守候未知里为你等待。
  • 相关阅读:
    顶级jQuery树插件
    jQuery 表格
    FlexiGrid使用手册
    gif动图快速制作方法(附工具)(转)
    Maven搭建SpringMVC+Hibernate项目详解(转)
    Gradle cookbook(转)
    Gradle入门系列(转)
    Gradle构建多模块项目(转)
    oracle中imp命令具体解释
    DisplayContent、StackBox、TaskStack笔记
  • 原文地址:https://www.cnblogs.com/zw130-lzr-blogs/p/11339464.html
Copyright © 2011-2022 走看看