分治法(求最大子序列和)

Posted Ponytai1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分治法(求最大子序列和)相关的知识,希望对你有一定的参考价值。

 1 //求出最大子序列 4 ,-3,5,-2,-1,2,6,-2 
 2 #include <stdio.h>
 3 int max (int a,int b,int c)
 4 {
 5     int ret;
 6     if(a > b)
 7     {
 8         ret = a;
 9     }else
10     if(a <= b)
11     {
12         ret = b;
13     }
14     if(ret >= c)
15     return ret;
16     else
17     return c;
18 }
19  int Findmaxsum(int box[],int size,int left,int right)      //参数(数组名,数组大小,左边界,右边界)
20 {
21     int mid = (right + left) / 2;
22     if(left == right)                                        //分治递归要注意出口条件
23     {
24         return box[left];
25     }
26     int leftsum = Findmaxsum(box,size,left,mid );           //求出左半区最大子序列和 ,要有递归信任,不要纠结层层深入,假设该函数是正确的。 
27     int rightsum = Findmaxsum(box,size,mid + 1,right);       //求出右半区最大子序列和
28     int leftbordersum = 0;
29     int rightbordersum = 0;
30     int i;
31     int thissum = 0;
32     for(i = mid + 1 ;i <= right;i++)                         //求出含有中间分界点的右半区最大子序列和  (如果最大子序列横跨中间分界点,那么肯定包含中间分界点,)
33     {
34         thissum += box[i];
35         if(rightbordersum < thissum)
36         {
37             rightbordersum = thissum;
38         }
39      } 
40      thissum = 0;
41      for(i = mid ;i >= left;i--)                          //求出含有中间分界点的左半区最大子序列和
42      {
43          thissum += box[i];
44          if(leftbordersum < thissum)
45          {
46              leftbordersum = thissum;
47          }
48      }
49      int midsum = leftbordersum + rightbordersum;               //横跨左右半区最大子序列和
50      return max(midsum,leftsum,rightsum);                        //左半区最大子序列和,右半区最大子序列和,跨半区最大子序列和,三者中最大的为所求者
51
52     
53 }
54 int main ()
55 {
56     int box[8] = {4,-3,5,-2,-1,2,5,-2};
57     int ret = 0;
58     ret = Findmaxsum(box,8,0,7);
59     printf("%d",ret);
60     return 0 ;
61  } 

遗留问题,此算法时间复杂度为 O(NlogN). 思考如何求得。

以上是关于分治法(求最大子序列和)的主要内容,如果未能解决你的问题,请参考以下文章

分治法 解决最大字段和问题

算法设计与分析--求最大子段和问题(蛮力法分治法动态规划法) C++实现

分治法求解最大子段和问题

0.分治永远大于顺序?关于最大子序列和问题的思考

分治法

分治算法解最大子序列和问题