AcWing 1051. 最大的和
宋标 Lv5

题目

对于给定的整数序列 ,找出两个不重合连续子段,使得两子段中所有数字的和最大。

我们如下定义函数

我们的目标就是求出

输入格式

第一行是一个整数 ,代表一共有多少组数据。

接下来是 组数据。

每组数据的第一行是一个整数,代表数据个数据 ,第二行是 个整数

输出格式

每组数据输出一个整数,占一行,就是 的值。

数据范围

,
,

输入样例:

1
10
1 -1 2 2 3 -3 4 -4 5 -5

输出样例:

13

样例解释

在样例中,我们取{2,2,3,-3,4}和{5}两个子段,即可得到答案。

题解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
#define N 50010
#define INF 0x3f3f3f3f

using namespace std;

int T;
int a[N], b[N], c[N];

int main()
{
ios::sync_with_stdio(false);
cin >> T;

while (T --)
{
int n;
cin >> n;
for (int i = 1; i <= n; ++ i) cin >> a[i];

b[0] = c[n + 1] = -INF;

// 前缀段最大和
int sum = 0;
for (int i = 1; i <= n; ++ i)
{
sum += a[i];
if (sum < a[i]) sum = a[i];
b[i] = max(sum, b[i - 1]);
}

// 逆序段最大和
sum = 0;
for (int i = n; i; -- i)
{
sum += a[i];
if (sum < a[i]) sum = a[i];
c[i] = max(sum, c[i + 1]);
}

// 取两段相加最大和
int ans = -INF;
for (int i = 1; i < n; ++ i)
ans = max(ans, b[i] + c[i + 1]);

cout << ans << endl;
}

return 0;
}
 评论