《算法导论》读书笔记--第四章 分治策略
在前面的章节中,曾经接触过分治策略,在分治策略中,要递归地解决难题,经历三个步骤:
分解(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; }
然而,有个地方还没搞清楚,就是如何返回最大连续子数组的下标。待我问问大牛。