poj 2479 Maximum sum 最大数字连续和

来源:互联网 发布:小米手机没有4g网络 编辑:程序博客网 时间:2024/05/16 11:05


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



解法:设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[n]=a[n];//对边界情况做特殊处理        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;}


0 0
原创粉丝点击