TYVJ1305 最大子序和
? 解题记录 ? ? 单调队列 ? ? 动态规划 ? ? 杂OJ ?    2018-03-24 15:03:16    805    0    0

题目描述

输入一个长度为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个数找到最大子序和

输出格式

一个数,数出他们的最大子序和

提示

数据范围:
100%满足n,m<=300000

样例数据

输入样例 #1输出样例 #1
6 4
1 -3 5 1 -2 3
7

本题我们要找一个不超过M长度的和最大的子段(可以不取)。那么直接把所有前缀和求出来,For一遍每一个右端点,用单调队列维护一下前面m个以内最小的前缀和是多少就行了

Code:

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 1e6 + 5;
int q[maxn][2], f = 1, b = 0, n, m, sum[maxn], mx = 0;

void push(int i, int x) {
	while(q[b][1] >= x && f <= b) --b;
	q[++b][0] = i, q[b][1] = x;
	if(q[f][0] <= i - m) ++f;
}

int main() {
	scanf("%d%d", &n, &m);
	for(register int i = 1; i <= n; ++i)
		scanf("%d", &sum[i]);
	for(register int i = 2; i <= n; ++i)
		sum[i] += sum[i - 1];
	for(register int i = 1; i <= n; ++i) 
		mx = max(mx, sum[i] - q[f][1]), push(i, sum[i]);
	printf("%d", mx);
	return 0;
}


上一篇: BZOJ1143: [CTSC2008]祭祀river

下一篇: 洛谷P1886 滑动窗口

805 人读过
立即登录, 发表评论.
没有帐号? 立即注册
0 条评论
文档导航