51nod 1094 循环数组最大子段和
解题思路:本问题跟之前和为k的连续区间解题算法稍有不同:
1.该题连续区间的范围是循环序列;
2.如果仍然使用上述算法会超时。
解题方法:
对于循环序列,需要考虑两种情况:
1.不考虑循环序列的情况下求出连续序列的最大值
2.若是最大值的产生情况是一部分取头+一部分取尾。则只需求出中间部分连续序列和为负数的最小值
对于第2种情况,可以把问题转化为求在对序列取反的情况下求中间部分和为正数的最大值。
最后比较1,2结果哪个大就选取哪个。
源码附上:
#include <iostream>
#include <algorithm>
using namespace std;
long long A[50001], temp[50001];
int N;
long long SumMax(long long B[])
{
temp[1] = A[1];
long long ans = 0;
for (int i = 1; i <= N; i++)
{
temp[i] = max(temp[i - 1] + A[i], A[i]);
ans = max(ans, temp[i]);
}
return ans;
}
int main()
{
long long sum = 0,sum1,sum2,result;
int i;
cin >> N;
for (i = 1; i <= N; i++)
{
cin >> A[i];
sum += A[i];
}
sum1 = SumMax(A);
for (i = 1; i <= N; i++)
{
A[i] = -A[i];
}
sum2 = SumMax(A);
sum2 = sum + sum2;
result = sum1>sum2 ? sum1 : sum2;
cout << result << endl;
return 0;
}