题目链接:
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1050
题解:
本题的思路主要分为两个方向:
1.就是正常的思路的时候,直接去求解最大子列和就行。
2.当最大的值出现的是收尾相连的时候的情况,这种时候,我们可以这么想:
出现这种情况的主要的原因就是,中的那段比较的小,导致了最大的值出现在了首尾,所以,换下思路,就是说将所有的值取反了以后,中间会出现最大值,而不是在首尾。
所以,综上,我们先计算总的和ans,在计算最大值的和ans1,然后讲数列进行取反操作,在进行取最大值ans2,然后再进行max(ans1,ans+ans2)(注:这里的ans2会将ans中的值抵消掉,直接剩下最大值)
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll maxn = 50000+10;
#define met(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
ll num[maxn];
int main()
{
ll n;
while(cin>>n)
{
ll ans=0,ans1=0,ans2=0;
for(ll i=0;i<n;i++)
{
cin>>num[i];
ans+=num[i];
}
ll sum1=0,sum2=0;
for(ll i=0;i<n;i++)
{
sum1+=num[i];
if(sum1>=ans1)
ans1=sum1;
if(sum1<0)
sum1=0;
}
for(ll i=0;i<n;i++)
num[i]*=(-1);
for(ll i=0;i<n;i++)
{
sum2+=num[i];
if(sum2>=ans2)
ans2=sum2;
if(sum2<0)
sum2=0;
}
cout<<max(ans1,ans+ans2)<<endl;
}
}