题目传送门

题目描述

给出一个长度为 n 的序列 a,选出其中连续且非空的一段使得这段和最大。

输入格式

第一行是一个整数,表示序列的长度 n

第二行有 n 个整数,第 i 个整数表示序列的第 i 个数字 ai

输出格式

输出一行一个整数表示答案。

输入输出样例

输入 #1 <button class="copy&#45;btn lfe&#45;form&#45;sz&#45;middle" data&#45;v&#45;1dc3ddfc="" data&#45;v&#45;7ade990c="" type="button">复制</button>
7
2 -4 3 -1 2 -4 3
输出 #1 <button class="copy&#45;btn lfe&#45;form&#45;sz&#45;middle" data&#45;v&#45;1dc3ddfc="" data&#45;v&#45;7ade990c="" type="button">复制</button>
4

说明/提示

样例 1 解释

选取 [3,5] 子段 {3,−1,2},其和为 4

数据规模与约定

  • 对于 40% 的数据,保证 n2×103
  • 对于 100% 的数据,保证1n2×105104ai104

题解:

这是一道很基础的前缀和的题目(前缀和板子题吧)

这题要求最大的子段和,我们可以按照前缀和的方法,用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;
}