1、分治法
/*
* 最大子段和
*/
int Maxsub(int *a, int begin, int end)
{
if(begin == end)
return a[begin];
else{
int mid, mleft, mright, mmiddle, mmiddle1, mmiddle2;
mid = (begin + end) / 2;
mleft = Maxsub(a, begin, mid);
mright = Maxsub(a, mid + 1, end);
int i, sum = 0;
sum = mmiddle1 = a[mid];
for(i = mid - 1; i >= begin; --i){
sum += a[i];
if(sum > mmiddle1)
mmiddle1 = sum;
}
sum = mmiddle2 = a[mid + 1];
for(i = mid + 2; i <= end; ++i){
sum += a[i];
if(sum > mmiddle2)
mmiddle2 = sum;
}
mmiddle = mmiddle1 + mmiddle2;
return (mleft > mright) ? (mleft > mmiddle ? mleft : mmiddle) : (mright > mmiddle ? mright : mmiddle);
}
}
2、动态规划
#include <iostream>
#include <cmath>
#include <ctime>
#define N 10
using namespace std;
int C[N];
int F[N];//用于追踪解首位置
struct Result{
int r;
int first;//注意这个下标是从零开始
int last;
}result;
void Maxsub(int *a, int begin, int end)//begin & end是数组的两个下标
{
int i, temp, last, first;
if (a[begin] > 0) {
C[begin] = a[begin];
F[begin] = begin;
first = begin;
last = begin;
} else {
C[begin] = 0;
F[begin] = -1;
first = -1;
last = -1;
}
temp = C[begin];
for (i = begin + 1; i <= end; ++i) {//后边界
if (C[i - 1] + a[i] > a[i]) {
C[i] = C[i - 1] + a[i];
F[i] = F[i - 1];
} else {
C[i] = a[i];
F[i] = i;
}
if (C[i] > temp) {
temp = C[i];
first = F[i];
last = i;
}
}
result.r = temp;
result.first = first;
result.last = last;
}
int main(){
int array[N];
srand((unsigned int)time(0));
for (int i = 0; i < N; ++i) {
array[i] = rand() % 100 - 50;
cout<<array[i]<<" ";
}
cout<<endl;
Maxsub(array, 0, N - 1);
cout<<"结果为:"<<result.r<<endl;
cout<<"数组下标范围为:"<<result.first<<" "<<result.last<<endl;
/*
for (int i = 0; i < N; ++i) {
cout<<C[i]<<" ";
}
cout<<endl;*/
return 0;
}
原理参见 屈婉玲老师 算法设计与分析 ORZ