题目链接:

AcWing

牛客

题目描述

输入一个长度为n的整数序列,从中找出一段不超过m的连续子序列,使得整个序列的和最大。

例如 1,-3,5,1,-2,3

当m=4时,S=5+1-2+3=7

当m=2或m=3时,S=5+1=6

输入描述:

第一行两个数n,m(\(n,m \leq 300000\))

第二行有n个数,要求在n个数找到最大子序和

输出描述:

一个数,数出他们的最大子序和

示例1

输入

6 4
1 -3 5 1 -2 3

输出

7

思路

单调队列

单调队列模板题

首先这是区间和的问题,先求前缀和 \(sum\)。题目转化为求最大的 \(sum[r] - sum[l]\) 且 \(r - l <= m\)。

枚举右端点 \(r\),维护左端点 \(l \in [r - m, r - 1]\),保持 \(sum[l]\) 最小。

如果某个位置 \(k < l\),且 \(sum[k] \ge sum[l]\),那么直接舍弃 \(k\)。因为 \(l\) 更靠近 \(r\) 且 \(sum[l] <= sum[k]\),这意味着 \(l\) 的生存能力更强。

因此维护一个前缀和递增的单调队列,保持队尾的元素的下标与队首的元素的下标之差不超过 \(m\)。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 3e5 + 10; int n, m;
ll sum[maxn];
int q[maxn]; void solve() {
ll ans = 0;
int l = 1, r = 1;
q[l] = 0;
for(int i = 1; i <= n; ++i) {
while(l <= r && i - q[l] > m) ++l;
ans = max(ans, sum[i] - sum[q[l]]);
while(l <= r && sum[i] <= sum[q[r]]) --r;
q[++r] = i;
}
cout << ans << endl;
} int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
for(int i = 1; i <= n; ++i) {
ll x;
cin >> x;
sum[i] = sum[i - 1] + x;
}
solve();
return 0;
}

deque 版本

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 3e5 + 10; int n, m;
struct Node {
int id; ll val;
} node[maxn]; void solve() {
ll ans = 0;
deque<Node> q;
for(int i = 1; i <= n; ++i) {
while(!q.empty() && i - q.front().id > m) q.pop_front();
ans = max(ans, node[i].val - q.front().val);
while(!q.empty() && node[i].val <= q.back().val) q.pop_back();
q.push_back(node[i]);
}
cout << ans << endl;
} int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
for(int i = 1; i <= n; ++i) {
ll x;
cin >> x;
node[i].val = node[i - 1].val + x;
node[i].id = i;
}
solve();
return 0;
}

参考

《算法竞赛进阶指南》 李煜东 著

CH1201 最大子序和 (单调队列)的更多相关文章

  1. CH 1201 - 最大子序和 - [单调队列]

    题目链接:传送门 描述输入一个长度为n的整数序列,从中找出一段不超过m的连续子序列,使得整个序列的和最大. 例如 $1,-3,5,1,-2,3$. 当 $m=4$ 时,$S=5+1-2+3=7$:当 ...

  2. CH1201 最大子序和

    http://contest-hunter.org:83/contest/0x10%E3%80%8C%E5%9F%BA%E6%9C%AC%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9 ...

  3. hdu 6319 逆序建单调队列

    题目传送门//res tp hdu 维护递增单调队列 根据数据范围推测应为O(n)的. 我们需要维护一个区间的信息,区间内信息是"有序"的,同时需要在O(1)的时间进行相邻区间的信 ...

  4. 单调栈&单调队列学习笔记!

    ummm,,,都是单调系列就都一起学了算了思想应该都差不多呢qwq 其实感觉这俩没有什么可说的鸭QAQ就是维护一个单调的东西,区别在于单调栈是一段进一段出然后单调队列是一段进另一段出?没了 好趴辣重点 ...

  5. tyvj1305 最大子序和 【单调队列优化dp】

    描述 输入一个长度为n的整数序列,从中找出一段不超过M的连续子序列,使得整个序列的和最大. 例如 1,-3,5,1,-2,3 当m=4时,S=5+1-2+3=7 当m=2或m=3时,S=5+1=6 输 ...

  6. Tyvj1305最大子序和(单调队列优化dp)

    描述 输入一个长度为n的整数序列,从中找出一段不超过M的连续子序列,使得整个序列的和最大. 例如 1,-3,5,1,-2,3 当m=4时,S=5+1-2+3=7当m=2或m=3时,S=5+1=6 输入 ...

  7. AcWing:135. 最大子序和(前缀和 + 单调队列)

    输入一个长度为n的整数序列,从中找出一段长度不超过m的连续子序列,使得子序列中所有数的和最大. 输入格式 第一行输入两个整数n,m. 第二行输入n个数,代表长度为n的整数序列. 同一行数之间用空格隔开 ...

  8. 【动态规划】【单调队列】tyvj1305 最大子序和

    http://blog.csdn.net/oiljt12138/article/details/51174560 单调队列优化dp #include<cstdio> #include< ...

  9. tyvj1305 最大子序和(单调队列

    题目地址:http://www.joyoi.cn/problem/tyvj-1305 最大子序和 题目限制 时间限制 内存限制 评测方式 题目来源 1000ms 131072KiB 标准比较器 Loc ...

随机推荐

  1. python运行时禁止生成pyc文件

    方法 在环境变量文件~/.bashrc中添加 export PYTHONDONTWRITEBYTECODE=False source ~/.bashrc加载即可 如何从项目中删除所有.pyc文件 fi ...

  2. 树状数据删除(TP5)

    应用场景:类似上图中树状菜单,选中一级菜单 点击上方删除按钮 所有子菜单删除 以下是代码截图(代码基于 TP5)

  3. Django框架(三十)—— 使用Vue搭建前台

    目录 vue的使用 一.创建vue项目 二.pycharm开发vue项目 1.安装vue.js插件 2.运行vue项目 三.vue项目的目录结构 四.vue的使用 1.创建新的组件 2.显示数据 3. ...

  4. Gradle教程

    Ant和Maven共享在Java市场上相当大的成功.ANT是在2000年发布了第一个版本的工具,它是基于程序编程思想的发展. 后来,人们在 Apache-Ivy的帮助下,网络接受插件和依赖管理的能力有 ...

  5. java部署:CentOS 7下Tomcat安装与配置教程(Tomcat开机启动)

    一.前言 1.本教程主要内容 Tomcat安装与基础配置 Tomcat开机启动配置 2.本教程适用范围与环境信息 适用范围 软件/工具 版本说明 CentOS CentOS 7 Tomcat Tomc ...

  6. H5 IOS 虚拟键盘不回落的问题

    在 H5 页面中,会发现在高版本的 IOS 系统中(ios12以上)和微信版本6.7.x以上,都会发现 input 等输入框,输入内容之后发现虚拟键盘消失,但是页面出现大面积白框. 解决办法(最后加上 ...

  7. Elastic-Job分布式任务调度

    任务调度是指系统为了自动完成特定任务,在约定的特定时刻去执行任务的过程,有了任务调度即可解放更多的人力由系统自动去执行任务. 多线程方式实现: Timer方式实现: ScheduledExecutor ...

  8. 微信小程序の页面路由

    微信小程序的页面路由由平台已栈的形式管理. 微信小程序的页面为什么会如此特殊呢,因为可视区域始终只有一个页面. 一.小程序页面的路由方式 小程序页面有6种路由方式:初始化.打开新页面.页面重定向.页面 ...

  9. Linux中目录结构以及VI编辑器常见的命令操作

    1.每个目录的详细介绍,先放一张目录的整体结构在这里 /bin:是Binary的缩写,用于存放经常使用的命令 /sbin:s代表Super User,用于存放系统管理员使用的命令 /home:存放普通 ...

  10. 关于 群晖 docker 百度云盘下载的使用心得

    因为有了群晖,所以想折腾一下看看有什么更多的功能,今天就来折腾一下群晖百度云盘下载.毕竟现在云盘都限速了嘛... 在群晖里,要想用到百度云盘下载,就需要有个小东西,就是docker.docker很简单 ...