51Nod-1050循环数组最大子段和

输入

第1行:整数序列的长度N(2 <= N <= 50000)
第2 - N+1行:N个整数 (-10^9 <= S[i] <= 10^9)

输出

输出循环数组的最大子段和。

输入示例

6
-2
11
-4
13
-5
-2

输出示例

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;
}

猜你喜欢

转载自blog.csdn.net/qq_40707370/article/details/81783078