第2 - N+1行:N个整数 (-10^9 <= S i i <= 10^9)
6
-2
11
-4
13
-5
-2
20
**************************************************************************
思路,其实我就是觉得很烦。很烦。
**************************************************************************
你可以把这个一串数字,分为以下几类:
(1)第一种,从开始最后都是递增的,也就是全加起来,就是最大值。
例:5 1 2 3 4 5
(2)第二种,中间的一部分大,两头加了,就变小了。循环也是中间的。
例:6 -1 0 5 -1 5 -1
(3)第三种,两头的大,中间一部分数值,阻隔了。循环去考虑。
例:5 5 -1 -2 5 -1
(4)第四种,就前面,或者后面的小,其余的是最大值的组成部分。
例:5 1 2 -1 0 -3 或者 5 -1 0 -3 1 2
**************************************************************************
现在我们来解决他们这些情况,就可以解决了。
(1)(4)我们用一个数值,求不循环的最大值,就可以解决掉。OK。
(2)(3)如果我们把所有的数取反,之后求最大值,得到的是不是小的部分加起来的最大值,之后再把原来的数据,加起来。他们求和,不就是最大值吗?假设原来全部数据和为ans1 ,取反求最大值为ans2,那么ans = ans1 + ans2吗?或者这样来理解,我们把原来的数据求最小值,我们用所有的数据和,减去他,ans = ans1 - (-ans2),公式不就是这个吗?只不过前者我取反求的ans2而已。
**************************************************************************
(1)(2)(3)(4)合并,二者之间不就是,去取最大值吗?
**************************************************************************
这种解释,应该能懂吧?或者还有什么情况没有考虑吗?欢迎下面留言,我将一一改正。
**************************************************************************
代码如下:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
long long int a[50005];
int n;
long long int cmp()
{
long long int max1 = 0;
long long int num = 0;
for(int i=0;i<n;i++)
{
if(max1<0) {
max1=a[i];
}
else {
num = max(num,max1);
max1+=a[i];
}
}
return num;
}
void print_gaibian()
{
for(int i=0; i<n; i++)
{
a[i] = -a[i];
}
}
int main()
{
scanf("%d",&n);
long long int ans=0,ans1=0,ans2=0;
for(int i=0;i<n;i++)
{
scanf("%lld",&a[i]);
ans+=a[i];
}
ans1 = cmp();
print_gaibian();
ans2 = cmp();
ans = max(ans1,ans+ans2);
printf("%lld\n",ans);
return 0;
}