题目描述:
给出一个整数序列S,其中有N个数,定义其中一个非空连续子序列T中所有数的和为T的“序列和”。
对于S的所有非空连续子序列T,求最大的序列和。
变量条件:N为正整数,N≤1000000,结果序列和在范围(-2^63,2^63-1)以内。
输入:
第一行为一个正整数N,第二行为N个整数,表示序列中的数。
输出:
输入可能包括多组数据,对于每一组输入数据,
仅输出一个数,表示最大序列和。
样例输入:
5
1 5 -3 2 4
6
1 -2 3 4 -10 6
4
-3 -1 -2 -5
样例输出:
9
7
-1
代码:
#include <iostream>
#include <cstdio>
#include <climits>
using namespace std;
typedef long long LL;
int n;
const int maxn = 1000001;
LL a[maxn];
LL max(LL a , LL b)
{
return a > b ? a : b;
}
void solve()
{
LL maxpre = 0 , maxnow = 0;
for(int i = 0 ; i < n ; i ++)
{
maxnow = maxnow + a[i];
if(maxnow < 0)
{
maxnow = 0;
}
if(maxnow > maxpre)
maxpre = maxnow;
}
cout << maxpre << endl;
}
int main()
{
#ifdef DoubleQ
freopen("in.txt" , "r" , stdin);
#endif // DoubleQ
while(cin >> n)
{
int flag = 0 , flag2 = 0;
LL maxx = LONG_MIN;
for(int i = 0 ; i < n ; i ++)
{
cin >> a[i];
if(a[i] != 0) flag = 1;
if(a[i] >= 0) flag2 = 1;
maxx = max(maxx , a[i]);
}
if(flag == 0)
{
cout << "0" << endl;
continue;
}
if(flag2 == 0)
{
cout << maxx << endl;
continue;
}
solve();
}
return 0;
}
作者提醒:
很经典的一道题。首先考虑一下细节问题,当序列都是0时,
显然最后要输出0;当序列都是负数时,显然要输出最大的数。
细节处理完了,就可以回到正常轨道。我们开两个变量,分别保存当前的序列和与之前的最大值,
我们更新当前序列和的条件是如果当前序列和是负数的时候,那我们必须更新,
否则一定会使最后结果减小。更新过程中还要更新之前最大值即可。