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