这个算法的运行时间?

时间:2020-03-23 15:10:46

标签: algorithm performance recursion

以下算法(使用动态编程)接受输入:C是整数,p是包含整数的数组,而np的大小。请注意,该代码是伪代码。

Start(C, p, n)
   let mem[1..C, 1..n] be a multi-dimensional array
   for i=1 to C
      for j=1 to n
         mem[i,j] = -1
   return Count(C, p, n, mem)

Count(C, p, i, mem)
   if mem[C, i] >= 0
      return mem[C, i]
   if C==0
      q = 1
   elif n < 1 or C < 0
      q = 0
   else
      q = Count(C - p[i], p, i-1, mem) + Count(C, p, i-1, mem)
   mem[C, i] = q
   return q

为什么将此实现的运行时间称为O(n * C)?

对于Count中的每个子问题,最多存在i-1个子问题,我们可以解决其中两个Count(C - p[i], p, i-1, mem)Count(C, p, i-1, mem)

因此,为什么运行时间不是O(n ^ 2)?我的意思是,如果我们为每个子问题解决i-1个子问题* 2,我们将得到一个算术级数为O(n ^ 2)?如果我错了,请告诉我:)

我们的C是肯定的,否则就没有界限。 C可能比n大,在这种情况下,由于n*C > n*n中数组的初始化,我看到O(n*C)暗示着Start。但是,如果C小于n,则n*C < n*n意味着O(n^2)。那你会说O(n*C)还是O(n^2)-为什么,为什么不呢?

1 个答案:

答案 0 :(得分:0)

此代码的运行时为O(nC)。一种查看方式是表中共有O(nC)个元素,并且由于备忘录的工作原理,您要花费O(1)的时间来填充每个元素。

您的问题似乎归结为是否可以将O(nC)重写为O(n 2 )。这取决于C是什么。如果C是可以独立于n变化的东西(例如,如果C可以是10 20 而n = 3),则O(nC)不能简化为O(n 2 )。

另一方面,如果C某种程度上受依赖于n的约束(例如,您知道C≤n),那么您可以说运行时间为O(n 2 )。那么问题是这是否有用。 O(nC)比O(n 2 )更精确,因为它更直接表明运行时开销取决于n和C,对于较小的C,您会更好地指示出运行多长时间使用O(nC)会比使用O(n 2 )约束时要复杂得多。

希望这会有所帮助!