最大子段和

https://www.luogu.com.cn/problem/P1115

贪心

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=2e5+7;
int a[maxn];
typedef long long ll;
ll ans=-inf;

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
   ll s=a[1];
   ll ans=a[1];
    for(int i=2;i<=n;i++)
    {

         if(s<0)
            s=0;
             s+=a[i];
         ans=max(ans,s);
    }

    printf("%lld\n",ans);
}

分治的方法

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=2e5+7;
int a[maxn];
  int n;
typedef long long ll;
ll ans=-inf;
int slove(int l,int r)
{ if(l==r)
return a[l];
    int mid=(l+r)>>1;
    ll lans=slove(l,mid);
    ll rans=slove(mid+1,r);
    ans=max(ans,max(lans,rans));
    ll q=0,h=0,mq=-inf,mh=-inf;
    for(int i=mid;i>=l;i--)
    {
        q+=a[i];
        mq=max(q,mq);
    }
    for(int i=mid+1;i<=r;i++)
    {
        h+=a[i];
        mh=max(h,mh);
    }
    return ans=max(ans,mq+mh);
}
int main()
{

    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
   slove(1,n);
    printf("%lld\n",ans);
}

每次分治更新需要和三个比较,左区间,右区间,中间的连接区间

posted @ 2021-07-20 17:50  废柴废柴少女  阅读(31)  评论(0)    收藏  举报