Maximum sum

描述

Given a set of n integers: A={a1, a2,..., an}, we define a function d(A) as below:

                     t1     t2 
d(A) = max{ ∑ai + ∑aj | 1 <= s1 <= t1 < s2 <= t2 <= n }
i=s1 j=s2


Your task is to calculate d(A).

输入

The input consists of T(<=30) test cases. The number of test cases (T) is given in the first line of the input. 
Each test case contains two lines. The first line is an integer n(2<=n<=50000). The second line contains n integers: a1, a2, ..., an. (|ai| <= 10000).There is an empty line after each case.输出Print exactly one line for each test case. The line should contain the integer d(A).

样例输入

1

10
1 -1 2 2 3 -3 4 -4 5 -5

样例输出

13

提示

In the sample, we choose {2,2,3,-3,4} and {5}, then we can get the answer.

Huge input,scanf is recommended.


题意: 给一串数列,前面一段+后面一段使最大(不能重合哦)

一个有趣的DP,正推一遍,更新前缀最优;同理,再倒推一遍,更新后缀最优

就好啦~

详见代码

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int sum[50001],pre[50001],bak[50001];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;++i) {
            scanf("%d",&sum[i]);
            sum[i]+=sum[i-1];
        }
        pre[1]=sum[1];
        int Mn=min(sum[1],0);
        for(int i=2;i<=n;++i) {
            Mn=min(Mn,sum[i]);
            pre[i]=max(pre[i-1],sum[i]-Mn);
        }    
        bak[n]=sum[n]-sum[n-1];
        int Mx=sum[n];
        for(int i=n-1;i>1;i--) {
            Mx=max(Mx,sum[i]);
            bak[i]=max(bak[i+1],Mx-sum[i-1]);
        }
        int ans=-1e9;
        for(int i=1;i<n;++i) {
            ans=max(ans,pre[i]+bak[i+1]);
        }
        printf("%d
",ans);
        memset(pre,0,sizeof(pre));
        memset(bak,0,sizeof(bak));
    }
    return 0;
}
从0到1很难,但从1到100很容易
原文地址:https://www.cnblogs.com/qseer/p/9624361.html