最大子段和(分治法&动态规划)

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 
#include 
#include 
#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<

原理参见 屈婉玲老师 算法设计与分析 ORZ

你可能感兴趣的:(最大子段和(分治法&动态规划))