算法笔记--最大子段和问题

Posted Wisdom+.+

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法笔记--最大子段和问题相关的知识,希望对你有一定的参考价值。

1.非连续最大子段和

如果不全为负数,最大子段和所有大于等于0的元素的和;如果全为负数,最大子段和为最大的负数。

2.连续最大子段和

①无长度限制:

例题:

洛谷p1115最大子段和

代码:

技术分享
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
const int N=2e5+5;
int a[N];
int main()
{
    int n;
    cin>>n;
    for(int i=0;i<n;i++)cin>>a[i];
    int temp=0;
    int ans=0;
    int maxn=-INF;
    bool flag=true;
    for(int i=0;i<n;i++)
    {
        temp+=a[i];
        maxn=max(maxn,a[i]);
        if(a[i]>=0)flag=false;
        if(temp<0)
        {
            temp=0;
        }
        ans=max(ans,temp);
    }
    if(flag)cout<<maxn<<endl;
    else cout<<ans<<endl;
    return 0;
}
View Code

 

 

安利一下我们学校的oj

zstuoj1361最大利益

代码:

技术分享
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
const int INF=0x3f3f3f3f;
int sum[N];
int a,maxsum,minsum;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin>>t;
    int l,r;
    int ansl,ansr,ans;
    for(int i=1;i<=t;i++)
    {
        memset(sum,0,sizeof(sum));
        maxsum=-INF;
        minsum=0;
        ans=-INF;
        int ma=-INF;
        l=0;
        int ll=0;
        bool flag=false;
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            int a;
            cin>>a;
            if(a>ma)
            {
                ma=a;
                ll=i;
            }
            if(a>=0)flag=true;
            sum[i]=sum[i-1]+a;
            if(sum[i]>maxsum)
            {
                maxsum=sum[i];
                r=i;
            }
            if(sum[i]<minsum)
            {
                minsum=sum[i];
                l=i;
            }
            if(sum[r]-sum[l]>ans&&r>l)
            {
                ans=sum[r]-sum[l];
                ansl=l+1;
                ansr=r;
            }
        }
        cout<<"Payoff "<<i<<":"<<endl;
        if(flag)cout<<ans<< <<ansl<< <<ansr<<endl;
        else cout<<ma<< <<ll<< <<ll<<endl;
        cout<<endl;
    }
    return 0;
}
View Code

 

②有长度限制(如最大连续奇数字段和)

杭电集训队排位赛

代码:

技术分享
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int a[N];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        for(int i=0;i<n;i++)cin>>a[i];
        int sum=a[0],ans=a[0];
        for(int i=1;i<n-1;i+=2)
        {
            sum+=a[i]+a[i+1];
            if(sum<a[i+1])sum=a[i+1];
            ans=max(ans,sum);
        }
        sum=a[1];
        for(int i=2;i<n-1;i+=2)
        {
            sum+=a[i]+a[i+1];
            if(sum<a[i+1])sum=a[i+1];
            ans=max(ans,sum);
        }
        cout<<ans<<endl;
    }
    return 0;
}
View Code

 

以上是关于算法笔记--最大子段和问题的主要内容,如果未能解决你的问题,请参考以下文章

最大子段和

关于求最大子段和的几种算法

算法竞赛进阶指南扩展最大子段和POJ1050ToTheMax

分治法求解最大子段和问题

分治算法总结(未完结)

算法设计与分析--求最大子段和问题(蛮力法分治法动态规划法) C++实现