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