码迷,mamicode.com
首页 > 其他好文 > 详细

最大子段和-蛮力法

时间:2020-05-07 13:52:11      阅读:85      评论:0      收藏:0      [点我收藏+]

标签:+=   return   str   情况   第一个   lse   std   保留   class   

问题描诉: 给定有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;
}

 

最大子段和-蛮力法

标签:+=   return   str   情况   第一个   lse   std   保留   class   

原文地址:https://www.cnblogs.com/xxaf/p/12842155.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!