【问题标题】:Can recursion be dynamic programming?递归可以是动态规划吗?
【发布时间】:2013-10-09 14:34:35
【问题描述】:

我被要求使用动态编程来解决问题。我对动态编程的构成有不同的看法。我相信它需要一种“自下而上”的方法,首先解决最小的问题。

我有一个矛盾的信息,如果相同的子问题被多次解决,是否可以是动态编程,递归中经常出现这种情况。

例如。对于斐波那契,我可以有一个递归算法:

RecursiveFibonacci(n)
if (n=1 or n=2)
    return 1
else
    return RecursiveFibonacci(n-1) + RecursiveFibonacci(n-2)

在这种情况下,可能会一遍又一遍地解决相同的子问题。这是否呈现它 不是 动态编程?也就是说,如果我想要动态编程,我是否必须避免解决子问题,例如使用长度为 n 的数组并将解决方案存储到每个子问题(数组的第一个索引是 1、1 , 2, 3, 5, 8, 13, 21)?

Fibonacci(n)
F1 = 1
F2 = 1
for i=3 to n
    Fi=Fi-1 + Fi-2
return Fn

【问题讨论】:

    标签: recursion dynamic-programming fibonacci


    【解决方案1】:

    动态程序通常可以用递归公式简洁地描述。

    但是,如果您使用简单的递归计算机程序来实现它们,这些通常会因为您提出的原因而效率低下:重复相同的计算。斐波那契是重复计算的一个例子,虽然它不是一个动态程序。

    有两种方法可以避免重复。

    1. 备忘录。这里的想法是缓存为递归函数的每组参数计算的答案,并在缓存值存在时返回它。

    2. 自下而上的表格。在这里,您“展开”递归,以便将低于 i 的级别的结果组合到级别 i 的结果。这通常被描述为填充表格,其中级别是行。

    任何 DP 算法都隐含其中一种方法。如果重复计算,则该算法不是 DP。所以你的问题的答案是“是的”。

    举个例子……假设你有价值为 v_1、v_2、... v_n 的硬币,让我们尝试用最少数量的硬币找零 c 美分的问题。

    令 N(c) 为赚取 c 美分所需的最小硬币数。那么一个递归公式是

    N(c) = 1 + min_{i = 1..n} N(c - v_i) 
    

    对于 k

    要记住这一点,只需要一个将 c 映射到 N(c) 的哈希表。

    在这种情况下,“表”只有一维,很容易填写。假设我们有值 1、3、5 的硬币,那么 N 表以

    开头
    • N(0) = 0,初始条件。
    • N(1) = 1 + min(N(1-1), N(1-3), N(1-5) = 1 + min(0, inf, inf) = 1
    • N(2) = 1 + min(N(2-1), N(2-3), N(2-5) = 1 + min(1, inf, inf) = 2
    • N(3) = 1 + min(N(3-1), N(3-3), N(3-5) = 1 + min(2, 0, inf) = 1

    你明白了。你总是可以用这种方式从 N(d), d

    在这种情况下,您只需记住最后 5 个值,因为那是最大的硬币值。大多数 DP 都是相似的。只需要表格的几行即可获得下一个。

    对于递归表达式中的 k 个自变量,该表是 k 维的。

    【讨论】:

    • 感谢吉恩。因此,为了澄清定义(这就是我真正追求的:o)),即使使用递归算法,它效率低下,因为可能会过度解决相同的问题 -再说一遍,它是否仍然算作动态规划,仅仅是因为较大的问题首先被分解为较小的问题?
    • @user2808302 不。不像我见过的那样使用这个词。动态程序或 DP 算法的基本假设是子问题只解决一次以获得更大的问题解决方案。当使用递归公式描述时,隐含记忆或自下而上的表格构造。
    【解决方案2】:

    如果有问题,我们会考虑一种动态编程方法

    1. 重叠子问题
    2. 最佳子结构

    用非常简单的话我们可以说动态编程有两个方面,它们是自顶向下和自底向上的方法。

    在您的情况下,如果您在谈论递归,这是一种自上而下的方法。 在自顶向下的方法中,我们将尝试编写递归解决方案或蛮力解决方案并记住结果,以便在类似的子问题到来时尝试使用该结果,所以它是蛮力+记忆。我们可以通过简单的递归关系来实现这种蛮力方法。

    【讨论】:

      猜你喜欢
      • 2014-05-22
      • 2012-09-20
      • 1970-01-01
      • 1970-01-01
      • 2015-12-31
      • 2015-10-04
      • 2014-06-26
      • 2013-11-14
      • 2012-07-10
      相关资源
      最近更新 更多