【问题标题】:Dynamic Programming: top down versus bottom up comparison动态规划:自上而下与自下而上的比较
【发布时间】:2023-03-23 03:11:01
【问题描述】:

您能否指出一些自下而上比自上而下更有益的动态编程问题陈述? (即简单的 DP 更自然,但记忆会更难实现?)

我发现带有记忆的递归要容易得多,并且希望解决自下而上是更好/也许是唯一可行的方法的问题。

我知道理论上两者是等价的,所以即使是易于实施之类的东西也可以算作好处。

【问题讨论】:

标签: dynamic-programming


【解决方案1】:

您将根据手头的问题应用自下而上的记忆化或自上而下的记忆化递归。

例如,如果您必须找到路径图的最小权重无关路径,您将使用自下而上的方法,因为您必须解决所有可能的子问题。

但是如果你必须解决背包问题,你可能需要使用递归自上而下的记忆,因为你必须解决有限数量的子问题。自下而上处理背包问题将导致算法解决许多原始子问题中未使用的冗余问题。

【讨论】:

    【解决方案2】:

    决定使用哪种算法时需要考虑的两件事

    1. 时间复杂度。两种方法通常具有相同的时间复杂度,但由于 for 循环比递归函数调用便宜,如果以 机器时间 衡量,自底向上可以更快。
    2. 空间复杂性。 (在自顶向下时不考虑额外的调用堆栈分配)通常两种方法都需要为所有子解决方案建立一个表,但自底向上遵循拓扑顺序,它的辅助空间成本有时可以减少到问题的大小直接依赖。例如:fibonacci(n) = fibonacci(n-1) + fibonacci(n-2),我们只需要存储过去两次计算即可

    话虽如此,自下而上并不总是最好的选择,我将尝试举例说明:

    1. (@Nikunj Banka 提到)自上而下仅解决您的解决方案使用的子问题,而自下而上可能会在冗余子问题上浪费时间。一个愚蠢的例子是 0-1 knapsack 有 1 个项目...运行时间差异是 O(1) 与 O(weight)
    2. 您可能需要执行额外的工作来获得自下而上的拓扑顺序。在Longest Increasing Path in Matrix中,如果我们想在它们的依赖之后做子问题,我们必须对矩阵的所有条目进行降序排序,这是在DP之前额外的nmlog(nm)预处理时间

    【讨论】:

      猜你喜欢
      • 2013-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-06
      • 2012-04-26
      • 1970-01-01
      • 1970-01-01
      • 2019-08-28
      相关资源
      最近更新 更多