最大子段和問題—分治法


一、問題描述

簡述

給定有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;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM