【51nod】最大子段和

题面

以一个长为n的数列,求连续子段的最大值。

思路1

直接枚举O(n^3)TLE稳稳的

#include<iostream>
using namespace std;
int n, a[50050], ans;
int main(){
    cin>>n;
    for(int i = 1; i <= n; i++)cin>>a[i];
    for(int i = 1; i <= n; i++){//枚举起点
        for(int j = i; j <= n; j++){//枚举终点
            int t = 0;
            for(int k = i; k <= j; k++){//区间统计
                t += a[k];
            }
            ans = max(ans, t);//更新最值
        }
    }
    cout<<ans<<"\n";
    return 0;
}

前缀和优化的枚举法,O(N^2),还是TLE

#include<iostream>
using namespace std;
int n, a[50050], ans;
int main(){
    cin>>n;
    for(int i = 1; i <= n; i++){ cin>>a[i]; a[i]+=a[i-1];}
    for(int i = 1; i <= n; i++)//枚举起点
        for(int j = i; j <= n; j++)//枚举终点
            ans = max(ans, a[j]-a[i-1]);//更新最值
    cout<<ans<<"\n";
    return 0;
}

思路2

分治。以中间元素为基准,向左求出以中间元素为尾的最大子段和,向右求出以中间元素为首的最大子段和,两部分相加即横跨左右两部分的最大子段的和,三者最大即为答案。复杂度O(nlogn),可以水过,记得不开longlong会WA。

#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
int n, a[50050];
LL dfs(int l, int r){
    if(l==r)return a[l]>0?a[l]:0;//所给整数均为负数时和为0。
    else{
        int m = l+r>>1;
        LL ls = dfs(l,m), rs = dfs(m+1,r);//左右两段单独
        //跨中间
        LL lsum = 0, lmax = 0;
        for(int i = m; i >= l; i--){
            lsum += a[i];
            lmax = max(lmax, lsum);
        }
        LL rsum = 0, rmax = 0;
        for(int i = m+1; i <= r; i++){
            rsum += a[i];
            rmax = max(rmax, rsum);
        }
        return max(lmax+rmax,max(ls,rs));
    }
}
int main(){
    cin>>n;
    for(int i = 1; i <= n; i++)cin>>a[i];
    cout<<dfs(1,n)<<"\n";
    return 0;
}

思路3

DP(覆盖了所有状态),如果当前记录的子段的和为负数时,就要以下一个点为起点重新找子段了。复杂度O(n),AC稳稳的。

#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
int n, a[50050];
int main(){
    cin>>n;
    for(int i = 1; i <= n; i++)cin>>a[i];
    LL ans=0, t=0;
    for(int i = 1; i <= n; i++){
        if(t > 0)t += a[i];
        else t = a[i];
        ans = max(ans, t);
    }
    cout<<ans<<"\n";
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_33957603/article/details/79980328