最大连续和

1、暴力求解 O(n3)

    int maxsum = a[1];
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            int sum = 0;
            for(int k = i; k <= j; k++) {
                sum += a[k];
            }
            maxsum = max(maxsum, sum);
        }
    }

2、预处理暴力求解 O(n2)

    int maxsum = a[1];
    s[0] = 0;
    //最大连续和等于两个前缀和之差
    for(int i = 1; i <= n; i++) {
        s[i] = s[i - 1] + a[i];
    }
    for(int i = 1; i <= n; i++) {
        for(int j = i; j <= n; j++) {
            maxsum = max(maxsum, s[j] - s[i - 1]);
        }
    }

3、分治法求解 O(nlogn)

int MaxSubSum(int l, int r) {
    int sum = 0;
    if(l == r) { //基本情况,只有一个元素
        return a[l];
    }
    int mid = (l + r) >> 1;
    int lsum = MaxSubSum(l, mid); //左半部分
    int rsum = MaxSubSum(mid + 1, r); //右半部分
    // 求包含左半部分最右元素的最大和
    int s1 = 0, ls = 0;
    for(int i = mid; i >= l; i--) {
        ls += a[i];
        s1 = max(s1, ls);
    }
    // 求包含右半部分最左元素的最大和
    int s2 = 0, rs = 0;
    for(int i = mid + 1; i <= r; i++) {
        rs += a[i];
        s2 = max(s2, rs);
    }
    //取三者最大值
    sum = s1 + s2;
    sum = max(sum, max(lsum, rsum));
    return sum;
}

4、动态规划 O(n)

// 状态转移方程
    //sum[i] = max(sum[i - 1] + a[i], a[i]); // sum[i]记录以a[i]为子序列末端的最大连续和
    int sum = 0, maxsum = 0;
    for(int i = 1; i <= n; i++) {
        if(sum > 0) {
            sum += a[i];
        } else {
            sum = a[i];
        }
        maxsum = max(maxsum, sum);
    }

猜你喜欢

转载自blog.csdn.net/qwqwdqwqwe/article/details/80055085
今日推荐