7-2 最大子段和(题目)
摘要:给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时,定义子段和为0。
要求算法的时间复杂度为O(n)。
首先,我们注意题目的两个关键点
1.连续的子段序列
2.特殊情况:当所有给出的整数都为负数的时候,定义子段和为0
3.算法实现复杂度为O(n)
解题思路
运用了动态规划,其中复习动态规划的两个基本性质,最优子结构,重复子问题
输入格式
输入有两行:
第一行是n值(1<=n<=10000);
第二行是n个整数。
输出格式
输出最大子段和
输入案例
6
-2 11 -4 13 -5 -2
输出案例
20
具体代码
#include <bits/stdc++.h>
using namespace std;
#define MAXSIZE 1000
int main() {
int num;
cin >> num;
int Array[MAXSIZE] = { 0 };//初始化Array数组
//在这里的思路最重要的就是确定动态规划的顺序,在这里我们首先确定Record数组里面的i的含义,
//在这里即为以i结尾的最大字段和,然后初始化第一个元素(因为已经已知)
//所以就是我们确定顺序为从左到右,而且当i个元素为负数的时候,考虑前面的Record为整数就相加,
//如果第i个元素为正数的时候,我们考虑前面的Record[i-1]是否为正数,如果为正整数就相加,如果为负数就Record[i]赋值为Array[i]
int Record[MAXSIZE] = { 0 };// Record[i]:以第i个数结尾的最大子段和
int flag = 0;// 记录负数的个数的
for (int i = 0; i < num; i++) {
cin >> Array[i];//输入数组的数值
if (Array[i] < 0) {
flag++;
}//统计数组的负数个数
}
if (flag == num) {
cout << 0;
}//当所给的整数均为负数时,定义子段和为0。
else {
Record[0] = Array[0];//初始化从第一个元素到第一个元素结束时候
for (int i = 1; i < num; i++) {
if (Record[i - 1] <= 0) Record[i] = Array[i];
else Record[i] = Record[i - 1] + Array[i];
}
int max = Record[0];
for (int i = 0; i < num; i++) {
if (max < Record[i]) {
max = Record[i];
}
}//选择最大的max,遍历寻找最大值
cout << max;
}
}
递归表达式(还没写学会怎么写)(见谅)
R
e
c
o
r
d
[
i
]
=
{
R
e
c
o
r
d
[
i
−
1
]
+
A
r
r
a
y
[
i
]
i
f
A
r
r
a
y
[
i
]
>
0
&
&
R
e
c
o
r
d
[
i
−
1
]
>
=
0
R
e
c
o
r
d
[
i
−
1
]
+
A
r
r
a
y
[
i
]
i
f
R
e
c
o
r
d
[
i
]
>
0
&
&
A
r
r
a
y
[
i
]
<
0
A
r
r
a
y
[
i
]
i
f
R
e
c
o
r
d
[
i
−
1
]
<
0
&
&
A
r
r
a
y
[
i
]
>
0
Record[i]=\Bigg\{ \frac{ Record[i-1]+Array[i] \ \ if\ Array[i]>0 \ \&\& \ Record[i-1]>=0}{Record[i-1]+Array[i] \ \ \ if\ Record[i]>0 \ \& \& Array[i]<0 } \ Array[i]\ if \ Record[i-1]\ <0 \ \& \& \ Array[i]>0
Record[i]={Record[i−1]+Array[i] if Record[i]>0 &&Array[i]<0Record[i−1]+Array[i] if Array[i]>0 && Record[i−1]>=0 Array[i] if Record[i−1] <0 && Array[i]>0
重要思想
在这里的思路最重要的就是确定动态规划的顺序,在这里我们首先确定Record数组里面的i的含义,
在这里即为以i结尾的最大字段和,然后初始化第一个元素(因为已经已知),不难推出第一个元素和从左到右的关系
所以就是我们确定顺序为从左到右,而且当i个元素为负数的时候,考虑前面的Record为整数就相加,
如果第i个元素为正数的时候,我们考虑前面的Record[i-1]是否为正数,如果为正数就相加,如果Record[i]为负数,Record[i]赋值为Array[i](因为Array[i]为正数)只有这样就能够确保数值最大。