输入一个长度为n的整数序列,从中找出一段长度不超过m的连续子序列,使得子序列中所有数的和最大。
输入格式
第一行输入两个整数n,m。
第二行输入n个数,代表长度为n的整数序列。
同一行数之间用空格隔开。
输出格式
输出一个整数,代表该序列的最大子序和。
数据范围
1≤n,m≤3000001≤n,m≤300000
输入样例:
6 4
1 -3 5 1 -2 3
输出样例:
7
#include#include using namespace std; deque q; int arr[300010]; int sum[300010]; int main() { int n, m; scanf_s("%d%d",&n,&m); memset(arr,0,sizeof(arr)); memset(arr, 0, sizeof(sum)); for (int i = 1; i <= n; i++) { scanf_s("%d",&arr[i]); sum[i] = sum[i - 1] + arr[i]; } int res = -INT_MIN; int l, r;//左区间与右区间 for (int i = 1; i <= n; i++) { while (!q.empty() && i - q.front() > m) {//?为什么是大于,因为你只需要保证sum[i]-sum[k]的长度M<=4 q.pop_front();//如果队列里面的数超过了m的话,就将前面的弹出 } int k; if (!q.empty()) k = q.front(); else k = 0; if (res < sum[i] - sum[k]) { res = max(res, sum[i] - sum[k]); l = k + 1; r = i; } while (!q.empty()&&sum[q.back()]>=sum[i]) {//利用前缀和来维护单调队列,根据前缀和的性质, q.pop_back(); } q.push_back(i);//保持Q中sum[]是单调不减的 } cout << res<<" "<



