最大子段和-蛮力法

Posted xxaf

tags:

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

问题描诉: 给定有n个整数(可能为负整数)组成的序列a1,a2,...,an,求该序列连续的子段和的最大值和区间。 如果该子段的所有元素和是负整数时定义其最大子段和为0。

输入:1 -2 4 5 -2 8 3 -2 6 3 7 -1

输出:32 , [3 , 11]

蛮力法:

时间:O(n3)

#include<iostream>

using namespace std;

int main()
{
    int a[20];
    int n;
    int max=0;
    int x,y;
    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 sum=0;
            for(int k=i;k<=j;k++)  //区间内的和
            {
                sum+=a[k];
            }
            if(sum>max)
            {
                max=sum;
                x=i,y=j;
            }
        }
    }
    if(max>0)
    {
        cout<<max<<" , ["<<x<<" , "<<y<<"]";
    }
    else
    {
        cout<<0;
    }
    return 0;
}

分治法:

时间:O(n*logn)

最大子段和的区间有三种情况:

技术图片

 

左半部分、右半部分和跨越中间部分

 

递归(左半部分,图片从上往下看,整体在从下往上看):

 

s1=左面最大子段和  s2=右面最大子段和  s3=s1+s2+他们中间的数

 

                                                 技术图片 

                                               s1=4  s2=11  s3=15,最大子段和为15,区间【4,8】

技术图片                                                                               技术图片

s1=1  s2=4  s3=3,最大子段和为4,区间【4】                    s1=5  s2=8  s3=11,最大子段和为11,区间【5,8】

 技术图片                                                                                    技术图片

s1=-2  s2=4  s3=2,最大子段和为4,区间【4】                  s1=-2  s2=8  s3=6,最大子段和为8,区间【8】

#include<iostream>
using namespace std;

int MaxSubArray(int a[],int left,int right)
{
    int mid=(left+right)/2;
    int s1,s2,sum=0;
    int max=-10000;  //max相当于s3
    if(left==right)
    {
        return a[left];
    }
    s1=MaxSubArray(a,left,mid);  //左递归
    s2=MaxSubArray(a,mid+1,right);  //右递归
    for(int i=mid;i>=0;i--)   //从左半部分最后一个数向前加找出最大值
    {
        sum+=a[i];
        if(max<sum)
        {
            max=sum;
        }
    }
    sum=max;  //保留最大值
    for(int i=mid+1;i<=right;i++)    //从右半部分第一个数向后加找出最大值
    {
        sum+=a[i];
        if(max<sum)
        {
            max=sum;
        }
    }
    if(max<s1)
    {
        max=s1;
    }
    else if(max<s2)
    {
        max=s2;
    }return max;
}
int main()
{
    int a[20];
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
    }
    cout<<MaxSubArray(a,0,n-1);
    return 0;
}

 

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

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

蛮力法——冒泡排序

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

01背包的蛮力法实现

最大子段和

线段树维护区间最大子段和