《算法导论》读书笔记--第四章 分治策略

在前面的章节中,曾经接触过分治策略,在分治策略中,要递归地解决难题,经历三个步骤:

分解(Divide) 将问题划分为一些子问题,子问题的形式与原问题相同,只是规模更小。

解决(Conquer)递归地求解出子问题,如果问题足够小,则停止递归,直接求解。

合并(Combine)将子问题的解组合成原问题的解。

本章就看到更多分治策略的算法,首先是最大和连续子数组问题,然后是两个求解n阶矩阵乘法的分治算法。其中一个复杂度为n立方,另一个是n的2.81次方。

--2016.2.23--

有三种方法可以求解递归式

  • 代入法:猜测一个界,再去生命它是对的
  • 递归树法:将递归树转换成一棵树,其结点表示不同层次的递归调用产生的代价。然后采用边界和技术来求解递归式
  • 主方法

4.1最大(连续)子数组问题

下面是代码:

#include <iostream>

using namespace std;

const int INF = 100000;

float FindMaxCrossSubarray(float* arr, int low, int mid, int high)
{
    float leftsum = -INF, rightsum = -INF;

    float sum = 0;
    for (int i = mid; i >= low; i--)
    {
        sum = sum + arr[i];
        if (sum > leftsum)
        {
            leftsum = sum;
        }
    }

    sum = 0;
    for (int j = mid + 1; j <= high; j++)
    {
        sum += arr[j];
        if (sum > rightsum)
        {
            rightsum = sum;
        }
    }

    return  leftsum + rightsum;
}


float FindMaxSubArray(float* arr, int low,int high)
{
    if (low == high)
    {
        return arr[low];
    }
    else
    {
        float leftsum,rightsum,midsum;
        int mid = (int)((low + high) / 2);

        leftsum = FindMaxSubArray(arr, low, mid);
        rightsum = FindMaxSubArray(arr, mid + 1, high);
        midsum = FindMaxCrossSubarray(arr, low, mid, high);

        if ((leftsum >= rightsum) & (leftsum >= midsum))
            return leftsum;
        else if ((rightsum >= leftsum) & (rightsum >= midsum))
            return rightsum;
        else
            return midsum;
    }

}

int main(){
    float arr[10] = { 1,-2,3,-4,5,6,-7,9,10,-8};
    int low = 0;
    int high = 9;

    float result = FindMaxSubArray(arr, low, high);

    cout << result << endl;

    return 0;
}

然而,有个地方还没搞清楚,就是如何返回最大连续子数组的下标。待我问问大牛。

原文地址:https://www.cnblogs.com/batteryhp/p/5183145.html