分治法,求最大字段和
问题: 给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整均为负数时定义子段和为0,依此定义,所求的最优值为: Max{0,a[i]+a[i+1]+…+a[j]},1<=i<=j<=n 例如,当(a[1],a[2],a[3],a[4],a[5],a[6])=(-2,11,-4,13,-5,-2)时,最大子段和为20。
分为三种情况,以中间划分,1.全在左边,2.全在右边 3.跨越了中间的mid(这种情况是易求的)
1,2情况按原问题做递归即可
// MaxChildArray.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <VECTOR> #include <iostream> using namespace std; //返回值,result[0]-> lindex result[1]-> rindex result[2]-> sum(lindex,rindex) vector<int> GetMaxAcross(vector<int> & v,int mid,int begin,int end){ int lsum = 0 ,maxlsum= -9999; int rsum = 0 ,maxrsum= -9999; vector<int > result(3,0); int i = 0; for(i = mid;i>=begin;i--){ lsum+=v[i]; if(maxlsum < lsum){ maxlsum = lsum; result[0] = i; } } for(i = mid+1;i<=end;i++){ rsum+=v[i]; if(maxrsum < rsum){ maxrsum = rsum; result[1] = i; } } result[2] = maxlsum+maxrsum; return result; } vector<int> GetMaxChildArray(vector<int> & v,int begin,int end){ vector<int > result(3,0); if(begin == end){ //递归截止点 result[0] = begin; result[1] = end; result[2] = v[end]; return result; } int mid = (begin+end)/2; vector<int> lresult = GetMaxChildArray(v,begin,mid); vector<int> rresult = GetMaxChildArray(v,mid+1,end); vector<int> midresult = GetMaxAcross(v,mid,begin,end); if(lresult[2] >= rresult[2] && lresult[2] >= midresult[2]) return lresult; if(rresult[2] >= lresult[2] && rresult[2] >= midresult[2]) return rresult; return midresult; } int main(int argc, char* argv[]) { int array[] = {-2,11,-4,13,-5,-2}; vector<int> elements(array,array+sizeof(array)/sizeof(int)); vector<int> result = GetMaxChildArray(elements,0,sizeof(array)/sizeof(int)-1); cout<<"leftindex = "<<result[0]<<endl; cout<<"rightindex = "<<result[1]<<endl; cout<<"maxsubarray = "<<result[2]<<endl; int i; cin>>i; return 0; }