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

最大子段和问题—分治法

时间:2020-11-27 10:54:27      阅读:3      评论:0      收藏:0      [点我收藏+]

标签:ace   分解   include   一个   --   put   names   math   有一个   

一、问题描述

简述

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

Input

第一行有一个正整数n(n<1000),后面跟n个整数,绝对值都小于10000。直到文件结束。

Output

输出它的最大子段和。

输入

6 -2 11 -4 13 -5 -2

输出

20

二、解题思路

分支法基本思想

将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。

解题思路

  1. 对于数组的最大子段和问题,它最大子段要么在左半边,要么在右半边,要么是穿过中间,三种情况
  2. 每次把N个字段在中间分成两段用递归直至字段分解成长度为一时在返回数组下标对应的数
  3. 每次递归得到左半边和右半边的最大字段后再求穿过中间的情况对应的最大子段,三者取最大值

三、代码

#include <iostream>
#include <math.h>
using namespace std;

int *p;
int f(int l,int r){
    if(l==r)
        return p[r];
    int mid = (l + r)/2;
    int t1 = f(l,mid);
    int t2 = f(mid+1,r);

    int maxl=0,maxr=0;
    int sum = 0;
    for(int i=mid;i>=l;i--){
        sum+=p[i];
        if(sum>maxl)
            maxl = sum;
    }
    sum = 0;
    for(int i=mid+1;i<=r;i++){
        sum+=p[i];
        if(sum>maxr)
            maxr = sum;
    }
    return max(max(t1,t2),maxl+maxr);
}

int main()
{
    int n;
    cin>>n;
    p = new int[n];
    for(int i=0;i<n;i++){
        cin>>p[i];
    }
    int res = f(0,n-1);
    cout<<res<<endl;

    return 0;
}

最大子段和问题—分治法

标签:ace   分解   include   一个   --   put   names   math   有一个   

原文地址:https://www.cnblogs.com/chengejie/p/14026163.html

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