输入
第1行:整数序列的长度N(2 <= N <= 50000) 第2 - N+1行:N个整数 (-10^9 <= S[i] <= 10^9)
输出
输出循环数组的最大子段和。
输入示例
6 -2 11 -4 13 -5 -2
输出示例
扫描二维码关注公众号,回复: 3070525 查看本文章20
解题思路:
最终答案存在两种可能性:
1、a[i]+a[i+1]+…+a[j],这种情况相当于求最大子段和
2、a[i]+a[i+1]+…+a[n]+a[1]…+a[j],这种情况因为总和一定所以我们求中间那段字段的最小值,然后用总和减去最小子段和就是最大字段和
所以两次dp就可以了
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e4+10;
const int INF=0x3f3f3f3f;
int main()
{
long long a[maxn],dp[maxn];
memset(dp,0,sizeof(dp));
long long sum=0,max1=0,minx2=INF,ans;
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
sum+=a[i];
}
for(int i=1;i<=n;i++)
{
dp[i]=max(dp[i-1]+a[i],a[i]);
max1=max(dp[i],max1);//最大子段和
}
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
{
dp[i]=min(dp[i-1]+a[i],a[i]);
minx2=min(minx2,dp[i]);//最小子段和
}
ans=max(max1,sum-minx2);
cout<<ans<<endl;
return 0;
}