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