题目描述
给出一段序列,选出其中连续且非空的一段使得这段和最大。
输入输出格式
输入格式:
第一行是一个正整数N,表示了序列的长度。
第二行包含N个绝对值不大于10000的整数A描述了这段序列。
输出格式:
一个整数,为最大的子段和是多少。子段的最小长度为11。
#include <iostream>
#include <algorithm>
using namespace std;
int a[200001] = {0},b[200001] = {0},c[200001] = {0};
int maxi = -99999,mini = 0;
int main()
{
int n = 0;
cin >> n;
for ( int i = 1;i <= n;i++)
{
cin >> a[i];
b[i] = b[i-1]+a[i];
}
mini = min(0,b[1]);
c[1] = a[1];
for (int i = 2;i <= n;i++)
{
c[i] = b[i] - mini;
mini = min(mini,b[i]);
}
for (int i = 1;i <= n;i++)
{
maxi = max(maxi,c[i]);
}
cout << maxi <<endl;
}
逻辑设计:
1.用一个数组a记录所有元素值;
2.用一个数组b记录a的前i项和;
3.用一个数组c记录i元素之前元素最大和。
== 核心代码 ==
mini = min(0,b[1]);
c[1] = a[1];
for (int i = 2;i <= n;i++)
{
c[i] = b[i] - mini;
mini = min(mini,b[i]);
}
我们先用0和b[1]比较:
如果b[1]小于0,显然,求c[2]的时候肯定要把b[1]减去,这样才能保证c[2]最大。
然后做一个循环,从c[2]开始,找到前i项和中最小的,并且将其减去,这样得到了前i项一个范围内最大的值,最后再进行排序,选出最大的值。