递归与分治策略解决最大字段和问题
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include <stdio.h> #include <stdlib.h> #include <time.h> #define MAX_N 20
int max3(int, int, int); int maxSubArrayAns(int []); int maxSubArray(int [], int, int);
//求三个数中的最大值 int max3(int a, int b, int c){
if(a > b) return a > c ? a : c;
else return b > c ? b : c;
}
//采用分治策略 int maxSubArray(int nums[], int left, int right) {
3、运行结果
4、结果分析
在这个程序中采用生成随机数的方法,产生 20 个分布在 0 左右的数字。用 过采用递归调用的方法,计算出最大字段和为 44
5、OS 及编译环境
Win7 64 位操作系统,VC6.0 的编译环境
3
int maxLeftSum, maxRightSum;//左右边的最大和 int maxLeftBorderSum, maxRightBorderSum;//含中间边界的左右部分最大和 int leftBorderSum, rightBorderSum;//含中间边界的左右部分当前和
//递归到最后的基本情况 if(left == right)
leftBorderSum += nums[i]; if(leftBorderSum > maxLeftBorderSum)
maxLeftBorderSum = leftBorderSum; } //求含中间边界的右部分的最大值 maxRightBorderSum = 0, rightBorderSum = 0;
if(nums[left] > 0Βιβλιοθήκη Baidu return nums[left];
else return 0;
//递归求左右部分最大值 int mid = (left + right) / 2, i; maxLeftSum = maxSubArray(nums, left, mid); maxRightSum = maxSubArray(nums, mid + 1, right); //求含中间边界的左部分的最大值 maxLeftBorderSum = 0, leftBorderSum = 0; for(i = mid; i >= left; i--){
n/2
i
max∑a[k] 和 max ∑a[k] ,
然 后 将 两 个 值 相 加 即 得 到 此 种 情 况 下 的 数 组 最 大 子 段 和 0<=i<=n/2 k=i
n/2+1<=i<=n k=n/2
最后分别求出三种情况的最大子段和,再比较三个子段和,最大的那个即为数组
的最大字段和。
2、代码及注释
int main() {
int nums[MAX_N];//定义一个最大长度为 20 的数组 int i;
srand(time(0));//随机数产生器 printf("array: \n"); //产生 MAX_N 个随机数 for( i = 0; i < MAX_N; i++) {
//随机数产生的规则
1
递归与分治策略---最大子段和问题
nums[i] = (int)(rand() % (MAX_N * 2) - MAX_N); printf("%d\t", nums[i]); } printf("\n"); //调用递归函数 printf("The max subsequen sum is %d.\n", maxSubArrayAns(nums)); return 0; }
递归与分治策略---最大子段和问题
递归与分治策略---最大子段和问题 1、问题的描述
给定由 n 个整数组成的序列(a1,a2, …,an),求该序列形如
的子段和的最大值 。
分治算法就是将一个问题分解成若干个小问题,对若干个小问题分别求解,最后
在合并起来。
最大子段问题可以分成三种情况
1.数组 a[1-n](即数组前 1 至 n 个元素) 的最大子段和 a[1-n/2]的最大子段相同 2 数组 a[1-n](即数组前 1 至 n 个元素) 的最大子段和 a[n/2+1-n]的最大子段相同 3.数组 a[1-n]的最大子段和是由 a[1-n/2]和 a[n/2+1-n]结合而成,求解方法为 则分别求出
2
递归与分治策略---最大子段和问题 for(i = mid + 1; i <= right; i++){
rightBorderSum += nums[i]; if(rightBorderSum > maxRightBorderSum)
maxRightBorderSum = rightBorderSum; } //返回三者中的最大值 return max3(maxLeftSum, maxRightSum, maxLeftBorderSum + maxRightBorderSum); } int maxSubArrayAns(int nums[]) { return maxSubArray(nums, 0, MAX_N - 1); }