最大子序和(数组模拟单调队列)

Posted mb62d0ca5a0a625

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最大子序和(数组模拟单调队列)相关的知识,希望对你有一定的参考价值。


问题 B: 最大子序和

题目描述
输入一个长度为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个数,要求在n个数找到最大子序和
输出
一个数,数出他们的最大子序和

样例输入 Copy
6 4
1 -3 5 1 -2 3
样例输出 Copy
7
提示
30%满足 n,m<=100
50%满足 n,m<=3000
100%满足n,m<=300000

  • 思路分析:
    单调队列
    需要满足两个性质:
  • 队列内具有一定的单调性(优先队列)。
    满足普通队列性质,一端进,另一端出,不可以中间插队。
    但是这样就会现矛盾了,例如一个单调增的队列:1,5,8,9,我们要插入4,这时如果只能从尾端进去的话就打破了其单调性,呢么这时的做法就是从队尾到队头,把大于4的全部T了,然后插入后的队列就变成了1,4。
  • 应用
    常用于优化动态规划(DP)问题。
    代码
#include<iostream>//线性筛素数
#include<math.h>
#include<stdio.h>
#include<string.h>
#include <algorithm>
#define
#define
const int mod=998244353;
using namespace std;
const int maxn=300006;

ll n,q,m,t,p,l,r,sum,c[maxn];
ll a[maxn],b[maxn];

int main ()
cin>>n>>m;
b[0]=0;
for(int i=1; i<=n; i++)
cin>>b[i];
b[i]+=b[i-1];

l = 1, r = 1, sum= -maxn;
c[1] = 0;
for (int i = 1; i <= n; i++)
while (l <= r && c[l] < i - m) l++;
sum = max(sum, b[i] - b[c[l]]);
while (l <= r && b[c[r]] >= b[i]) r--;
c[++r] = i;

cout<<sum<<endl;
return 0;


以上是关于最大子序和(数组模拟单调队列)的主要内容,如果未能解决你的问题,请参考以下文章

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

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

AcWing135. 最大子序和 单调队列

TYVJ 1305 最大子序和 题解 单调队列优化DP

单调队列与DP

最大子序和