您的位置:首页 > 其它

poj 2479 Maximum sum 最大数字连续和

2016-03-07 09:17 435 查看
昨天周赛,我被我的做法和代码给恶心到了,不仅做法麻烦易错,而且代码啰嗦的要命,本来很简单的问题,却被做成一副惨状。特意修改了代码。

解法:设R[i]为以a[i]结尾的最大连续子段和,L[i]为以a[i]开头的最大连续子段和。

很显然枚举x,答案就是L[x]+max{R[j]} (1<=j<x)。

其中max{R[j]}可以预处理,令dp[x-1]=max{L[j]} (1<=j<x)。

题目的要求:必须有两个子段。

L[x]+max{R[j]} (1<=j<x)一定满足有两子段

具体实现:

R[i]=max(R[i-1]+a[i],a[i]);

L[i]=max(L[i+1]+a[i],a[i]);

dp[i]=max(dp[i-1],R[i]);

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
const int INF =0x3f3f3f3f;
const int maxn=50000    ;
int n,T;
int a[maxn+5];
int R[maxn+5],L[maxn+5];
int dp[maxn+5];
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
R[1]=a[1];//对边界情况做特殊处理
for(int i=2;i<=n;i++)
{
R[i]=max(R[i-1]+a[i],a[i]);
}
L
=a
;//对边界情况做特殊处理
for(int i=n-1;i>=1;i--)
{
L[i]=max(L[i+1]+a[i],a[i]);
}

int ans=-INF;//此处要赋值为负无穷
dp[1]=a[1];//对边界情况做特殊处理
for(int i=2;i<=n;i++)
{
dp[i]=max(dp[i-1],R[i]);
ans=max(ans, L[i]+dp[i-1]  );
}
printf("%d\n",ans);

}

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