1305:Maximum sum
【输入样例】
1
10
1 -1 2 2 3 -3 4 -4 5 -5
【输出样例】
13
【提示】
就是求最大子段和问题,样列取2,2,3,−3,4和5,Baidu搜POJ 2479 Maximum sum,可获得大量经典最大子段和问题的题目解析,本题O(n2)算法超时,必须用O(n)算法。
思路:从左到右分别求出它们所在位置的最大连续和,然后从右到左求出它们所在的最大连续和,接着就是A[i]+B[i+1],A数组代表着从左到右,B代表着从右到左所以不断的比较A[0]+B[1],A[1]+B[2]求最大值即可,怎样求解最大值(如果当前的数据和小于零,很明显,将它加入到后面的计算中,肯定会减少最大值很简单的道理,-1+4<0+4,如果之前的取值小于零,抛弃它,重新赋值为零,然后通过maxs不断更新当前的最大值。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=50000+5;
int T,m;
int a[maxn];
int dp[maxn];
int main() {
scanf("%d",&T);
while(T--) {
scanf("%d",&m);
for(int i=0; i<m; i++) {
scanf("%d",&a[i]);
}
dp[0] = a[0];
int sum = a[0];
int ans = a[0];
for(int i = 1; i < m; i++) {
if(sum < 0) {//如果之前的取值小于零,抛弃它,重新赋值为零
sum = 0;
}
sum += a[i];
if(sum > ans) {
ans = sum;
}
dp[i] = ans;
}
sum = a[m-1];
int Max = dp[m-2] + sum;
ans = a[m-1];
for(int j = m-2; j >= 1; j--) {
if(sum < 0) {
sum = 0;
}
sum += a[j];
if(sum > ans) {
ans = sum;
}
Max = max(Max,dp[j-1]+ans);//通过Max不断更新当前的最大值
}
printf("%d\n",Max);
}
return 0;
}