【问题标题】:Dynamic Programming recursive or iterative动态规划递归或迭代
【发布时间】:2011-11-09 22:32:00
【问题描述】:

可以以“迭代”和“递归”方式应用动态编程,还是仅以其中一种方式应用它是一种好习惯?

【问题讨论】:

    标签: dynamic-programming


    【解决方案1】:

    可以将动态编程(在许多情况下)视为反向实现的递归解决方案。

    通常,在递归中,您将计算 x(n+1) = f(x(n)) 并为 n=0(或其他一些值)设置一些停止条件。

    在许多情况下,函数f 是一些最小/最大函数,但它不是必须的。 此外,该函数不必采用单个变量。

    动态编程将通过计算f(0)f(1)f(2) 等来解决这个问题。

    如果有多个变量,通常会有一些自然顺序来计算函数。

    动态规划可以解决的一个例子: 您将获得 3 个高尔夫球杆。每个高尔夫球杆可以将高尔夫球向前发送 x 个单位的距离(例如,24、37 和 54 个单位)。问题是:你能打出正好 200 单位外的洞吗?如果可以,您需要的最少拍摄次数是多少。

    递归解决方案类似于:

    shots(200) = min(shots(200-24),shots(200-37),shots(200-54))
    

    这将允许一个简单的实现,如果 n 为 0,函数 shot(n) 返回 0,如果 n 小于 0,则返回一个巨大的数字,否则上面的表达式。

    但是,对于较大的 n 值,您将一次又一次地从上面表达式的不同分支中找到相同的值。在这种情况下,最好从 0 开始计算shots(0)shots(1)shots(2) 等。这将是该问题的“动态规划”解决方案——使用线性时间和恒定空间而不是指数时间(遍历三向树)和线性空间(对于调用堆栈)。

    【讨论】:

    • 如果你加入记忆,自上而下的方法仍然被认为是动态编程。自下而上的 DP 和自上而下的 DP 都是 DP。
    • @harold 你说得对,我可能应该添加一些关于记忆的东西(如果你想保持合理的内存要求,它会更难使用,你需要知道什么时候可以“忘记" 值,而自下而上则非常清楚)。
    • 虽然带有缓存的递归解决方案只查看数字 0..200 的一小部分,但迭代解决方案必须查看所有这些数字(至少要避免这种情况并不简单) .因此,在这种情况下,递归解决方案似乎会运行得更快。
    • @MeirGoldenberg 这真的取决于确切的数字,不是吗?使用 1、3 和 5 个单位,递归不会很稀疏。总距离为 120,000 的递归(有或没有记忆)将需要比 DP 更多的内存。可以找到每种方法最有效的地方。
    • 我完全同意 Omri 并想问以下问题。对于 DP(带缓存)的自上而下递归方法将导致比迭代方法更简单的解决方案的问题的经典示例是什么?此线程中问题的“稀疏”版本就是一个示例,但我正在寻找一个受实际应用程序启发的问题。
    【解决方案2】:

    是的,DP 可以同时应用于两者。

    从这里开始:http://en.wikipedia.org/wiki/Dynamic_programming

    那么你有Dynamic Programming: From novice to advancedA Tutorial on Dynamic Programming

    对于第一个教程,您将找到 TopCoder.com 练习题的链接(每个问题都有一个 Editorial 解释解决方案背后的想法。

    【讨论】:

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