博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AcWing 最大子序和
阅读量:4485 次
发布时间:2019-06-08

本文共 1273 字,大约阅读时间需要 4 分钟。

AcWing 最大子序和

Description

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

Input

  • 第一行输入两个整数n,m。

    第二行输入n个数,代表长度为n的整数序列。

    同一行数之间用空格隔开。

Output

  • 输出一个整数,代表该序列的最大子序和。

Data Size

  • 1≤n,m≤300000

Sample Input

6 41 -3 5 1 -2 3

Sample Output

7

题解:

  • 单调队列。
  • 一般区间和的题都转换成前缀和来做。那么这题的基本元素就确定为前缀和。因为随着下标递增,区间的右边界每次都是固定的,所以只需要左边界最小即可。那么问题就成了“找到一个左端点j,使得sum[j]最小(i - m <= j <= i - 1)”。单调决策自然就出来了。
#include 
#include
#include
#define N 300005using namespace std;struct Node {int val, pos;};int n, m, ans = -0x7fffffff;int sum[N];deque
deq;int read(){ int x = 0, f = 1; char c = getchar(); while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();} while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();} return x *= f;}int main(){ cin >> n >> m; for(int i = 1; i <= n; i++) sum[i] = sum[i - 1] + read(); deq.push_back((Node){0, 0}); for(int i = 1; i <= n; i++) { while(deq.size() && deq.front().pos <= i - m - 1) deq.pop_front(); while(deq.size() && deq.back().val >= sum[i]) deq.pop_back(); deq.push_back((Node){sum[i], i}); ans = max(ans, sum[i] - sum[deq.front().pos]); } cout << ans; return 0;}

转载于:https://www.cnblogs.com/BigYellowDog/p/11312641.html

你可能感兴趣的文章
laravel的orm作用
查看>>
文件锁
查看>>
props和state
查看>>
LeetCode:Unique Paths I II
查看>>
AcWing 兔子与兔子
查看>>
洛谷 P3871 [TJOI2010]中位数
查看>>
洛谷 P2073 送花
查看>>
洛谷 P1801 黑匣子_NOI导刊2010提高(06)
查看>>
洛谷 P1503 鬼子进村
查看>>
E. The shortest problem
查看>>
进制转换——9018——1065
查看>>
老男孩Python全栈开发(92天全)视频教程 自学笔记21
查看>>
ASP.NET页面传值之Server.Transfer 和Response.Direct
查看>>
git随笔
查看>>
codeforces 985C. Liebig's Barrels
查看>>
获取URL参数
查看>>
异步数据处理Handler
查看>>
线段树lazy标记??Hdu4902
查看>>
Google Map API 学习四
查看>>
Hibernate入门1
查看>>