【问题标题】:Runtime of top down dynamic programming algorithm自顶向下动态规划算法的运行时间
【发布时间】:2020-03-02 20:27:21
【问题描述】:

我为一项任务提出了以下算法。主要是第 23-24 行中的 for 循环让我不确定。

function TOP-DOWN-N(C, n, p)
  let N[1...n, 1...C] be a new array initialized to -1 for all indicies
  return N(C, n)

function N(C, n)
  if N[C,n] >= 0 then
    return N[C,n]
  if C < 0 or n < 1 then
    return 0
  elif C = 0 then
    return 1
  elif C > 0 and i > 0 then
    r = 0
    for i = 0 to n do
      r += N(C-p[n-i], n-(i+1))
    N[C,n] = r
    return N

【问题讨论】:

  • 至于分析,您是正确的,最多 O(nC) 调用可能花费 O(1) 时间以上,但您仍然需要计算花费 O(1) 时间的那些因为可能有很多。
  • 花费 O(1) 时间的那些不会改变算法的运行时间将为 O(nC),对吗?我现在用伪代码把它打出来。
  • 如果发生循环的地方有 O(nC) 个调用,并且每个调用都有一个 O(n) 次迭代的循环,那么总复杂度应该是 O(n^2 C),应该不是吗?这是假设循环体花费恒定的时间,这不是严格正确的,但是是一种有效的简化,因为已经考虑了从循环内进行的递归调用。但是,循环本身执行 O(n) 次函数调用和 O(n) 次加法。
  • 你可能是对的。让我失望的是 - 如果函数调用终止为 N[C,n] >= 0 那么这将不会到达 for 循环。
  • 要使N[C,n] &gt;= 0 条件为真,那么它在过去的某个时刻一定是假的,具有相同的Cn 值,否则该数组单元将永远不会有已写入。

标签: algorithm time time-complexity dynamic-programming


【解决方案1】:

让我们忽略这个算法是递归实现的事实。一般来说,如果动态规划算法正在构建一个包含 N 个结果的数组,并且计算每个结果需要使用该数组中的 k 个其他结果的值,那么它的时间复杂度是 Ω(Nk),其中 Ω 表示一个 下限。这应该很清楚:使用 k 值来计算结果需要 Ω(k) 时间,并且您必须这样做 N 次。

另一方面,如果计算不做任何渐近比从数组中读取 k 值更耗时的事情,那么 O(Nk) 也是一个上限,因此时间复杂度为 Θ(Nk)。


因此,按照这种逻辑,我们应该期望您的算法的时间复杂度为 Θ(n2C),因为它构建了一个大小为 nC 的数组,计算每个结果使用 Θ(n)该数组的其他结果,并且该计算不受其他事物的支配。

但是,您的算法比迭代实现具有优势,因为它不必计算数组中的每个结果。例如,如果数字 1 不在数组 p 中,那么您的算法将不会为任何 n' 计算 N(C-1, n');如果p 中的数字都大于或等于C,则循环只执行一次,运行时间主要取决于必须初始化大小为nC 的数组。

由此可知 Θ(n2C) 是最坏情况时间复杂度,最好情况时间复杂度是 Θ(nC)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-26
    • 2013-11-27
    • 1970-01-01
    相关资源
    最近更新 更多