分治法(2):最大子段和

题目:

给定n个元素的整数列(可能为负整数)

a1,a2,,an.

求形如:ai,ai+1,aj(i/j=1n,i<=j)的子段

使其和为最大。当所有整数为负整数时定义其最大字段和为0

例如当(a1,a2,a3,a4,a5,a6=(-2,11,-1,13,-5,-2)

最大字段和为i=2,j=4(下标从1开始).

 

如果直接用经典二分法,我们发现,原问题被分成了两个独立的问题,这是不符合题目的。因此我们在左右两部分的基础上,再加上中间部分,进行求解

#include<bits/stdc++.h>
using namespace std;
int a[200005];
int n;
int max_mid(int mid)//中间部分
{
    int s1=a[mid],lefts=0;//不能写零,不然处理不了全负数的数据 
    for(int i=mid;i>=1;i--)
    {
       lefts+=a[i];
       s1=max(s1,lefts);
    }
    int s2=a[mid+1],rights=0;
    for(int i=mid+1;i<=n;i++)
    {
        rights+=a[i];
        s2=max(s2,rights);
    }
    return s1+s2;
}
int max_sum(int left,int right)
{
    int mid=(left+right)/2;
    if(left==right)//结束条件:left==right
    {
        return a[mid];
     } 
//二分
int maxleft=max_sum(left,mid); int maxright=max_sum(mid+1,right); int maxmid=max_mid(mid); return max(max(maxleft,maxright),maxmid); } int main() { cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; } cout<<max_sum(1,n)<<endl; }

 

posted @ 2022-04-06 22:14  格蕾  阅读(336)  评论(0)    收藏  举报