分治策略
来源:互联网 发布:全国矢量数据 编辑:程序博客网 时间:2024/05/29 15:09
分治策略
步骤:
- 分解
- 解决
合并
递归情况和基本情况:求解递归式时,可以使用三种方法,a 代入法 b 递归树法 c 主方法
最大子数组
A[low..high]的任何连续子数组A[i..j]所处的位置必然是以下几个情况之一:
- 完全位于子数组A[low..mid] low<=i<=j<=mid
- 完全位于子数组A[mid..high] mid
FIND_MAX_CROSSING_SUBARRAY(A, low, mid, high)left_sum = -无穷sum = 0for i = mid downto low sum = sum + A[i] if (sum > left_sum) left_sum = sum max_left = iright_sum = -无穷sum = 0for j = mid+1 to high sum = sum + A[j] if (sum > right_sum) right_sum = sum max_right = jreturn (max_left, max_right, left_sum + right_sum)
接下来,就能给出最大子数组问题的分治算法伪代码了
FIND_MAXIMUM_SUBARRAY(A, low, high)if (high == low) return (low, high, A[low])else mid = (low + high)/2 //向下取整 (left_low, left_high, left_sum) = FIND_MAXIMUM_SUBARRAY(A, low, mid) (right_low, right_high, right_sum) = FIND_MAXIMUM_SUBARRAY(A, mid+1, high) (cross_low, cross_right, cross_sum) = FIND_MAX_CROSSING_SUBARRAY(A, low, mid, high) if (left_sum >= right_sum && left_sum >= cross_sum) return (left_low, left_high, left_sum) else if (right_sum >= left_sum && right_sum >= cross_sum) return (right_low, right_high, right_sum) else return (cross_low, cross_high, cross_sum)
可以通过计算递归式发现,分治方法得到的这个最大子数组问题的时间复杂度优于暴力求解的O(n*n),得到的时间复杂度为O(n*lgn)
简单实现下:
#include <stdio.h>#include <stdlib.h>void result_save(int result[], int source[]);void find_maximum_subarray(int A[], int low, int high, int result[]);void find_max_crossing_subarray(int A[], int low, int mid, int high, int result[]);void find_max_crossing_subarray(int A[], int low, int mid, int high, int result[]){ int max_left; int max_right; int left_sum = -1; int sum = 0; for (int i = mid; i >= low; --i) { //left sum += A[i]; if (sum > left_sum) { left_sum = sum; max_left = i; } } int right_sum = -1; sum = 0; for (int j = mid+1; j <= high; ++j) { sum += A[j]; if (sum > right_sum) { right_sum = sum; max_right = j; } } result[0] = max_left; result[1] = max_right; result[2] = left_sum + right_sum; //sum}void find_maximum_subarray(int A[], int low, int high, int result[]){ if (low == high) { result[0] = low; result[1] = high; result[2] = A[low]; } else { int mid = (low + high)/2; int result1[3] = {0, 0, 0}; find_maximum_subarray(A, low, mid, result1); int result2[3] = {0, 0, 0}; find_maximum_subarray(A, mid+1, high, result2); int result3[3] = {0, 0, 0}; find_max_crossing_subarray(A, low, mid, high, result3); if (result1[2] >= result2[2] && result1[2] >= result3[2]) result_save(result, result1); else if (result2[2] >= result1[2] && result2[2] >= result3[2]) result_save(result, result2); else result_save(result, result3); }}void result_save(int result[], int source[]){ result[0] = source[0]; result[1] = source[1]; result[2] = source[2];}int main(void){ int A[16] = {13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7}; int result[3] = {0, 0, 0}; find_maximum_subarray(A, 0, 15, result); printf("the max sum is %d\n", result[2]); printf("the maximum number array is : "); for (int i = result[0]; i <= result[1]; ++i) printf("%d ", A[i]); exit(0);}
0 0
- 分治策略
- 分治策略
- 分治策略
- 分治策略
- 分治策略
- 分治策略
- 分治策略
- 分治策略
- 分治策略
- 分治策略
- 分治策略
- 分治策略
- 分治策略
- 分治策略
- Divide & Conquer 分治策略
- 递归与分治策略
- 分治策略----快速排序
- 递归与分治策略
- java web文件下载功能实现
- 一个循环还没结束另外一个循环又将开启
- html编辑的基本知识
- CSS排版观念
- 123
- 分治策略
- Xamarin Mono For Android 4.20 安装、破解
- (1224)HDU
- 读懂Java中的Socket编程
- OpenLayers中的球面墨卡托投影
- ssh框架如何同时使用两个数据库
- 公民委托诉讼代理人的注意事项
- Android:多语言对应
- 手机SD卡不能格式化怎么办