TYVJ1305 最大子序和

Posted 嘒彼小星

tags:

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

P1305 最大子序和
时间: 1000ms / 空间: 131072KiB / Java类名: Main

描述

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

输出格式

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

测试样例1

输入

6 4
1 -3 5 1 -2 3

输出

7

备注

数据范围:
100%满足n,m<=300000
 
【题解】
给前缀和维护一个单调递增的队列
技术分享
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #define max(a, b) ((a) > (b) ? (a) : (b))
 6 #define min(a, b) ((a) < (b) ? (a) : (b))
 7 
 8 inline void swap(int &a, int &b)
 9 {
10     int tmp = a;a = b;b = tmp;
11 }
12 
13 inline void read(int &x)
14 {
15     x = 0;char ch = getchar(), c = ch;
16     while(ch < 0 || ch > 9)c = ch, ch = getchar();
17     while(ch <= 9 && ch >= 0)x = x * 10 + ch - 0, ch = getchar();
18     if(c == -)x = -x;
19 }
20 
21 const int INF = 0x3f3f3f3f;
22 const int MAXN = 300000 + 10;
23 
24 int n, m, sum[MAXN], q[MAXN], rank[MAXN], head, tail, ans;
25 
26 int main()
27 {
28     read(n), read(m);
29     for(register int i = 1;i <= n;++ i) read(sum[i]), sum[i] += sum[i - 1];
30     head = tail = 1;
31     ans = -INF;
32     for(register int i = 1;i <= n;++ i)
33     {
34         while(i - rank[head] > m)++ head;
35         ans = max(ans, sum[i] - q[head]);
36         while(q[tail] >= sum[i] && tail >= head)-- tail;
37         ++ tail; 
38         q[tail] = sum[i], rank[tail] = i;
39         
40     } 
41     printf("%d", ans);
42     return 0;
43 }
TYVJ1305

 

以上是关于TYVJ1305 最大子序和的主要内容,如果未能解决你的问题,请参考以下文章

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

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

最大连续子序列问题(tyvj1305)

单调队列与DP

代码题(25)— 最大子序和最长上升子序列

java刷题--53最大子序和