您的位置:首页 > 其它

poj 2479 Maximum sum

2013-04-16 23:55 267 查看
题目意思不再重复,先解决一个最长段的问题,从头开始累加,加一次更新一次最大值,当sum<0时,从下一个数字开始累加。

现在解决两个段的问题,和最大的两个子段(A,B),要么都跟最长段(T)没有交集,要么把最长段一分为二。

简单证明下:如果跟最长短相交的话,那么设相交的为A,那么设A减去A和T的交集的字段和为sum

如果sum<0 那么把这段去掉能得到更优的解

如果sum>0 那么把这段加到T上面能得到更大的连续子段,矛盾。

证毕。

#include <iostream>

#include <cstdio>

#include <cstring>

using namespace std;

const int maxn=5e4+9;

int n;

int a[maxn];

int cal(int s,int t,int &st,int &ed,int tmp)

{

int ret=-11111,sum=0,_st=1;

for(int i=s;i<=t;i++)

{

sum+=a[i]*tmp;

if(sum>ret)

{

ret=sum;

st=_st;

ed=i;

}

if(sum<0)

{

_st=i+1;

sum=0;

}

}

return(ret);

}

int main()

{

int T;

for(scanf("%d",&T);T>=1;T--)

{

scanf("%d",&n);

for(int i=1;i<=n;i++)

scanf("%d",&a[i]);

int st,ed,tt;

int ans=cal(1,n,st,ed,1);

int ret=max(cal(1,st-1,tt,tt,1),cal(ed+1,n,tt,tt,1));

int _ret=max(0,cal(st,ed,tt,tt,-1));

if(ed-st>=1)

ans+=max(ret,_ret);

else

ans+=ret;

printf("%d\n",ans);

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: