434
社区成员
发帖
与我相关
我的任务
分享将a[1:n]分成两段:a[1:n/2], a[n/2+1:n],分别求出这两段的最大字段和,则a[1:n]的最大子段和有三种可能:
1、 a[1:n]的最大字段和与a[1:n/2]的最大子段和相同
2、a[1:n]的最大字段和与a[n/2+1]:n的最大子段和相同
3、a[1:n]的最大字段和为 a[i] + a[i+1] + a[i+2] + ...... + a[j-1] + a[j], 其中 1 <= i <= n/2 ; n/2+1 <= j <= n ;
编写函数MaxSubSum(int *a, int left, int right)
{先判断是否满足边界条件:数组中只有一个数据,
满足再判断该数据是否大于0,满足则返回该数据
否则
{
将数组分成左右两部分a[1:n/2], a[n/2+1:n],
再分别递归调用函数MaxSubSum
(若为前两种可能,则可以求出答案,接下来写第三种可能
若为第三种可能,则最大子段和中必定包含 a[n/2] 和 a[n/2+1],故 i 和 j 分别从 center = left + ( right - left ) / 2 和 center + 1 开始,i 自减,j 自增)
for 求出左边数据从a[center]开始往左累加的最大和s1;
for 求出右边数据从a[center+1]开始往右累加的最大和s2;
把s1+s2、leftsum、rightsum中最大的赋值给sum;
}
返回sum
}
定义函数MaxSum(int n, int*a{
返回 MaxSubSum(a, 1, n);
}
T(n)= O(1) n <= 0; //数组中只有一个数据
2T(n/2) + O(n) n >= 0; //分成两个子问题O(1),对两个子问题求解2T(n/2),合并子问题 O(n);
解得T(n) = O(nlogn);
分治法的基本思想是将一个难以直接解决的大问题,分解成为若干规模较小的容易解决的相同问题,以便各个击破,分而治之
三个步骤:
1、分解子问题
2、求解子问题(递归的调用正在设计的算法)
3、合并子问题的解,形成原始问题的解
常用算法设计模式:
dp(P)
{
if(|p| < n) return jfhhj(P) //表示边界条件,直接求解
分解子问题 p1, p2, p3, p4......., pk;
for( i = 1; i <= k; i ++)
{
y i = dp(P i)/ 递归解各子问题
return merge(yi......yk) /表示将子问题的解合并成P的解