题目描述
给出一个长度为 n 的序列 a,选出其中连续且非空的一段使得这段和最大。
输入格式
第一行是一个整数,表示序列的长度 n。
第二行有 n 个整数,第 i 个整数表示序列的第 i 个数字 ai。
输出格式
输出一行一个整数表示答案。
输入输出样例
输入
7
2 -4 3 -1 2 -4 3
输出
4
说明/提示
样例 1 解释
选取 [3,5] 子段 {3,−1,2},其和为 4。
数据规模与约定
- 对于 40% 的数据,保证 n≤2×103。
- 对于 100% 的数据,保证 1≤n≤2×105,−104≤ai≤104。
代码
无注释版
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+10;
int a[N],f[N];
int s=-2147483647;
signed main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
f[i]=max(f[i-1]+a[i],a[i]);
s=max(s,f[i]);
}
cout<<s;
}
有注释版
#include<bits/stdc++.h> // 引入标准库,包含常用的C++库
using namespace std; // 使用标准命名空间
#define int long long // 将 int 类型重新定义为 long long,保证处理较大数值时不会溢出
const int N = 2e5 + 10; // 定义常量 N,表示数组的最大大小,保证能容纳最大输入数据
int a[N], f[N]; // a 数组存储输入的序列,f 数组用于动态规划存储每个位置的最大子数组和
int s = -2147483647; // 初始化 s 为一个极小值,用来保存最大的子数组和
signed main() {
int n; // 输入序列的长度
cin >> n; // 输入 n 的值
// 输入序列 a
for(int i = 1; i <= n; i++) {
cin >> a[i]; // 逐个读取序列的元素
}
// 动态规划求解最大子数组和
for(int i = 1; i <= n; i++) {
// f[i] 表示以第 i 个元素结尾的最大子数组和
// 状态转移:f[i] = max(f[i-1] + a[i], a[i])
// f[i-1] + a[i] 表示当前子数组延续前一个子数组,a[i] 表示当前子数组从当前元素开始
f[i] = max(f[i-1] + a[i], a[i]);
// 更新最大子数组和 s
s = max(s, f[i]);
}
cout << s; // 输出最终的最大子数组和
}