AcWing:135. 最大子序和(前缀和 + 单调队列)
Posted buhuiflydepig
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AcWing:135. 最大子序和(前缀和 + 单调队列)相关的知识,希望对你有一定的参考价值。
输入一个长度为n的整数序列,从中找出一段长度不超过m的连续子序列,使得子序列中所有数的和最大。
输入格式
第一行输入两个整数n,m。
第二行输入n个数,代表长度为n的整数序列。
同一行数之间用空格隔开。
输出格式
输出一个整数,代表该序列的最大子序和。
数据范围
1≤n,m≤3000001≤n,m≤300000
输入样例:
6 4
1 -3 5 1 -2 3
输出样例:
7
算法:前缀和 + 单调队列
注意:单调队列需要使用双端队列deque,因为其中需要头部弹出以及尾部弹出。
#include <iostream> #include <cstdio> #include <deque> using namespace std; #define INF 0x3f3f3f3f const int maxn = 3e5+7; deque<int> que; int arr[maxn]; int sum[maxn]; int main() int n, m; scanf("%d %d", &n, &m); for(int i = 1; i <= n; i++) scanf("%d", &arr[i]); sum[i] = sum[i - 1] + arr[i]; int ans = -INF; for(int i = 1; i <= n; i++) while(!que.empty() && i - que.front() > m) //如果队列里面的数超过了m的话,就将前面的弹出 que.pop_front(); int k; if(que.size() > 0) k = que.front(); else k = 0; ans = max(ans, sum[i] - sum[k]); while(!que.empty() && sum[que.back()] >= sum[i]) //利用前缀和来维护单调队列,根据前缀和的性质, que.pop_back(); que.push_back(i); cout << ans << endl; return 0;
以上是关于AcWing:135. 最大子序和(前缀和 + 单调队列)的主要内容,如果未能解决你的问题,请参考以下文章