最大子序列和的【分治递归】求法

首先标明递归的四要素:

关于(1)基准情形,是说必须有不用递归就能求解的情况。否则,递归将永远进行下去。
可以看下这个例子:
int badRecursion( int n )
{
        if ( n == 0 )
            return 0;
        else 
            return badRecursion ( n/3 + 1 ) + n - 1;
}
你可以算一下,当计算到badRecursion(1)时,将一直计算下去。因为他没有一个终止循环的条件。

(2)(3)很好理解,就不说了。
(4)是说递归算法的效率性。
可以看一下这个递归算法:
long fib(int n)
{
    if ( n <= 1 )
        return 1;
    else
        return fib( n - 1 ) + fib( n - 2 );
}
这个算法看起来是个递归,可是当把n的数值调大后会发现它的效率低的惊人。简单分析一下就可以看出,最后一行语句第一次调用 fib(n-1) 实际上同时计算了fib(n-2)。这个信息被抛弃而在最后一行语句第二次调用时又重新计算了一遍。这违反了准则(4)。这可以解释为什么不用递归计算斐波那契数了。

 

下面是代码和注解 

 

 1 int  maxSumRec(const vector<int>&a,int left,int right)  
 2 
 3 {  
 4 
 5     int maxLeftSum,maxRightSum; //表示  
 6 
 7     int rightBorderSum = 0,leftBorderSum = 0;  
 8 
 9     int maxLeftBorderSum = 0,maxRightBorderSum = 0;  
10 
11     int center;  
12 
13     if(left == right) //解决小容量情况,当序列只有一个元素时,非负则返回唯一值,否则返回0(基准情况)  
14 
15     {  
16 
17         if(a[left]>0)  
18 
19         {  
20 
21             return a[left];  
22 
23         }else 
24 
25         {  
26 
27             return 0;  
28 
29         }  
30 
31     }  
32 
33     center = (left+right)/2;  
34 
35     maxLeftSum = maxSumRec(s,left,center); //每次递归返回时,该值为该子段的最终左最大子序列和  
36 
37     maxRightSum = maxSumRec(s,center+1,right); //每次递归返回时,该值为该子段的右最大自序列和  
38 
39     for(int i=center;i>=left;i--) //从中间向左扩展求子段的最大子序列和,必然包括子段的最右端数  
40 
41     {  
42 
43         leftBorderSum+=s[i];  
44 
45         if(leftBorderSum>maxLeftBorderSum)  
46 
47         {  
48 
49             maxLeftBorderSum = leftBorderSum; //包含左端数的最大子序列和  
50 
51         }  
52 
53     }  
54 
55     for(int j=center+1;j<=right;j++) //从中间向右扩展求子段的最大子序列和,必然包括子段的最左端数  
56 
57     {  
58 
59         rightBorderSum += a[j];  
60 
61         if(rightBorderSum > maxRightBorderSum)  
62 
63         {  
64 
65             maxRightBorderSum = rightBorderSum; //包含右端数的最大子序列和  
66 
67         }  
68 
69     }  
70 
71     //返回左子最大序列和,右最大子序列,及横跨中间的最大子序列和三者的最大值  
72 
73     return max3(maxLeftSum,maxRightSum,maxLeftBorderSum+maxRightBorderSum);   
74 
75 }   

 

posted @ 2016-04-14 16:55  朴者  阅读(772)  评论(0编辑  收藏  举报