分治法求最大子序列,关于复杂度的一次弱推导

   1:  #include <stdio.h>
   2:  #include <stdlib.h>
   3:   
   4:  int sc=0;
   5:  int max3(int a,int b, int c)
   6:  {
   7:      sc++;
   8:      if(a>b)
   9:      {
  10:          return a>c?a:c;
  11:      }
  12:      else
  13:      {
  14:          return b>c?b:c;
  15:      }
  16:  }
  17:   
  18:  int max_sub_sum(const int v[], int left, int right)
  19:  {
  20:      int center;
  21:      int maxLeftHalfSum;
  22:      int maxRightHalfSum;
  23:      int leftHalfWithRightBorderSum;
  24:      int rightHalfWithLeftBorderSum;
  25:      int maxLeftHalfWithRightBorderSum;
  26:      int maxRightHalfWithLeftBorderSum;
  27:      int i;
  28:   
  29:      if(left==right)
  30:      {
  31:          return v[left]>0?v[left]:0;
  32:      }
  33:      center=(left+right)/2;
  34:   
  35:      maxLeftHalfWithRightBorderSum=leftHalfWithRightBorderSum=
  36:      maxRightHalfWithLeftBorderSum=rightHalfWithLeftBorderSum=0;
  37:      for(i=center;i>=left;i--)
  38:      {
  39:          leftHalfWithRightBorderSum+=v[i];
  40:          if(leftHalfWithRightBorderSum>maxLeftHalfWithRightBorderSum)
  41:          {
  42:              maxLeftHalfWithRightBorderSum=leftHalfWithRightBorderSum;
  43:          }
  44:      }
  45:   
  46:      for(i=center+1;i<=right;i++)
  47:      {
  48:          rightHalfWithLeftBorderSum+=v[i];
  49:          if(rightHalfWithLeftBorderSum>maxRightHalfWithLeftBorderSum)
  50:          {
  51:              maxRightHalfWithLeftBorderSum=rightHalfWithLeftBorderSum;
  52:          }
  53:      }
  54:   
  55:      return max3(max_sub_sum(v,left,center),max_sub_sum(v,center+1,right),
  56:                  maxLeftHalfWithRightBorderSum+maxRightHalfWithLeftBorderSum);
  57:  }
  58:   
  59:  int main()
  60:  {
  61:      int v[]={1,-1,2,-2,5,-3,4,-4};
  62:      int r=max_sub_sum(v,0,7);
  63:      printf("the max sub sum is %d in step %d",r,sc);
  64:      return 0;
  65:  }

sc 用来统计max3执行的次数,这其实也是递归函数调用的次数,不妨假设N为2的整数次幂运算,即N=2k ,很明显依分治思路sc=1+21+22+…=20+21+22+…2k-1=2k-1=N-1.

通过简单推理可以知道sc其实就是把问题分治之后的所有子集的规模

众所周知该算法的复杂度为O(NlogN),现在我们来看一下复杂度T(N)是怎麽求解出来的:

T(N)=N*20 +(N/2k-1)*21+(N/2k-2)*22+…(N/2)2k-1 =(k-1)*N                    //注意此处推导,是基于sc的推到结果,复杂度近似等于求和sc的每一次递归调用产生的37~53步的循环次数,还不知道如何输入求和符号。。汗

而k显然为logN,此处对数底为2,于是我们大致推导出算法的复杂度为N*(logN-1).

posted @ 2012-06-15 08:56  Dance With Automation  Views(439)  Comments(0)    收藏  举报