将递归转换为动态&计算其时间复杂度

时间:2013-04-30 13:23:54

标签: recursion time-complexity dynamic-programming recurrence

我正在解决一个代码,我的递归函数就像这样 - >

int rec(n)
{

  if(n>=(n/2+n/3+n/4))
  {
      return n;
  }


  else
  {

     return  rec(n/2) + rec(n/3) + rec(n/4); 

  }

}

我想知道这个函数的时间复杂度是什么?

我认为递归关系是 -

T(n) = T(n/2) + T(n/3) + T(n/4) + f(n)

如何解决这种递归关系?在这种情况下,f(n)的值是多少?

另外,如何将其转换为动态编程?

我为将其转换为动态而编写的代码是 -

    long long  rec(long long n)
{
    long long c[n]; // The number range is between 1 to 10^9


    for(int i=0;i<n;i++)
    c[n]=0;


    if(n>=(n/2+n/3+n/4))
    {
        c[n]=n;
        return n;
    }
    else
    {
        if (c[n]==0)
        c[n]=c[n/2]+c[n/3]+c[n/4];
        return c[n];
    }

}

然而,在将递归转换为动态后,我的程序拒绝显示正确的答案。我想我还没有把它转换成动态编程。你能指导一下如何去做吗?

由于

1 个答案:

答案 0 :(得分:1)

if(n> =(n / 2 + n / 3 + n / 4))基本上等于if(n <= 0)。 n不能小于0,所以可以写if(n == 0)返回n;这意味着时间复杂度由以下递推方程给出:

T(0) = 1
T(n) = T(n/2) + T(n/3) + T(n/4)

由于在较小问题中划分问题不是对称的(因为n / 2 + n / 3 + n / 4 = 13n / 12,这大于n)在第一次近似(一个大的)我会在O(nlogn)和O(n ^ 2)之间说。我试图证明它是O(nlog2n)但没有检出(通过log2n我的意思是登录n的基数2):

T(n) <= cnlog2n

从现在开始,我将只写logn

T(n) <= cn/2*logn/2 + cn/3*logn/3 + cn/4*logn/4
      = cn/2*logn - cn/2*log2 + cn/3*logn - cn/3*log3 + cn/4*logn - cn/4*log4
      = cn/2*logn - cn/2 + cn/3*logn - cn/3*log3 + cn/4*logn - cn/2
      = 13/12*cn*logn - cn(log3/3 - 1) 

不小于或等于cnlogn

O(n ^ 2)可以证明是这样的:

if T(n) = O(n^2) then T(n) <= cn^2
T(n) <= c(n/2)^2 + c(n/3)^2 + c(n/4)^2
      = cn^2/4 + cn^2/9 + cn^2/16
      = 15cn^2/36 <= cn^2

所以O(n ^ 2)假设是正确的,但它可能不是很准确。 你可以尝试O(nlogn)和O(n ^ 2)之间的另一个假设,看看它们是否像我上面那样真实。