第九章 動態規劃-1305:Maximum sum

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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章