题目描述
给出一个长度为 n 的序列 a,选出其中连续且非空的一段使得这段和最大。
输入格式
第一行是一个整数,表示序列的长度 n。
第二行有 n 个整数,第 i 个整数表示序列的第 i 个数字 ai。
输出格式
输出一行一个整数表示答案。
输入输出样例
输入 #1 <button class="copy-btn lfe-form-sz-middle" data-v-1dc3ddfc="" data-v-7ade990c="" type="button">复制</button>
7
2 -4 3 -1 2 -4 3
输出 #1 <button class="copy-btn lfe-form-sz-middle" data-v-1dc3ddfc="" data-v-7ade990c="" type="button">复制</button>
4
说明/提示
样例 1 解释
选取 [3,5] 子段 {3,−1,2},其和为 4。
数据规模与约定
- 对于 40% 的数据,保证 n≤2×103。
- 对于 100% 的数据,保证1≤n≤2×105,−104≤ai≤104。
题解:
这是一道很基础的前缀和的题目(前缀和板子题吧)
这题要求最大的子段和,我们可以按照前缀和的方法,用sum[i]存前i项和,当sum[i]<=0的时候,我们让sum[i]=0,然后进行前缀和(如果小于0的话,那么后面的加上前面的一定是在减小的,就没有加的必要了)。
代码:
#include<iostream>
using namespace std;
const int N = 200010;
long long sum[N];
int a[N];
int n;
long long ans=-1000000;//先让ans最小
//最终答案可能为负数
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
sum[i] = sum[i - 1] + a[i];//前缀和
ans = max(sum[i], ans);//取大的
if (sum[i] <= 0)//如果小于0,那么便舍弃前面的
{
sum[i] = 0;
}
}
cout << ans;
}