POJ 2479 Maximum sum (求2个不相交的连续字段和的最大值)

题意如标题

分析:

  给定某一数组s1,s2,s3,...,sn,求一连续si,s(i+1),s(i+2),...,sj使其和最大.

    这个问题有一个简单的DP思路,先把状态转移方程写出:sum[n]=max{sum[n-1],0}+s[n].此状态方程用语言描述:

在求sum[n]时,若前n-1个数中所求得的连续和最大值都小于0时,则把前n-1个数抛弃,从第n个数重新算后面的sum[].

实现时可以不用数组存sum,而只用一个s初始值为0,把s1,s2,...,sn一个一个顺序地加,当s<0时s=0,当s>max时,max=s;

最后求得的max即为此问题所求,复杂度为o(n).

     对于poj2479来说,问题要麻烦一点,但只要弄明白了上面这个问题,这个题并不难,把数组分成s[1...i]和s[i+1...n]两部

分,枚取i,分别求出两部分的最大和,然后相加后取最大值即为问题所求.

     故只需要    从左往右扫一遍求最大连续字段和,然后再从右向左扫一遍求最大连续字段和。


#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define INF 0xffffff
using namespace std;

int a[50010],dp[50010];

int main()
{
    int T,n,sum,ans,tmp;
    scanf("%d",&T);
    while(T--)
    {
        memset(dp,0,sizeof(dp));
        memset(a,0,sizeof(a));

        scanf("%d",&n);
        sum=0;
        tmp=-INF;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            sum+=a[i];
            if(sum>tmp)
                tmp=sum;
            dp[i]=tmp;
            if(sum<0) sum=0;
        }
        sum=0;
        tmp=-INF,ans=-INF;
        for(int i=n;i>=2;i--)
        {
            sum+=a[i];
            if(tmp<sum)
                tmp=sum;
            if(tmp+dp[i-1]>ans)
                ans=tmp+dp[i-1];
            if(sum<=0) sum=0;
        }
        printf("%d\n",ans);
    }
    return 0;
}



POJ 2479 Maximum sum (求2个不相交的连续字段和的最大值)

上一篇:区块链项目等定制开发


下一篇:Codeforces Round #224 (Div. 2)