【问题标题】:How is "dynamic" programming different than "normal" programming?“动态”编程与“正常”编程有何不同?
【发布时间】:2012-03-18 11:10:03
【问题描述】:

每当我查看计算机竞赛的解决方案时,我总是会看到“动态编程”这个术语。我在谷歌上搜索了这个术语并阅读了几篇文章,但没有一篇提供编程 VS “动态”编程的简单示例。那么“动态”编程与“正常”编程有何不同? (请用简单的术语!)

【问题讨论】:

标签: algorithm dynamic-programming


【解决方案1】:

“正常”编程是指 C++/Java/C# 编程,对吧?

动态编程不是那种意义上的“编程”。它不是关于编写代码,而是在通过将复杂问题分解为更简单的问题来解决复杂问题的上下文中使用“编程”这个词。

【讨论】:

  • 它类似于基于分治的编程吗?
【解决方案2】:

Dynamic Programming 使用编程更多地与Linear Programming 一起使用——一种解决问题的机制。

我最近阅读的一个描述(但不再记得出处——[需要引用])表明recursion 中使用的divide and conquer 的常用方法是自上而下解决问题的方法,而 动态规划是一种自下而上的解决问题的方法。

Wikipedia 文章建议计算 Fibonocci sequence 是动态编程的一个很好的用途——在计算 memoize 的结果时,您可以在算法中进一步使用它们,以避免重新计算类似的结果。

Knuth's algorithm for line-breaking paragraphs 是动态编程的另一个很好的例子:如果您考虑在每个单词之间插入换行符的可能性(甚至在连字符点处 inside 单词中插入换行符),感觉就像只有算法才会是指数级的——或者更糟。但是,通过跟踪与先前换行符相关的“坏处”,Knuth 的算法实际上在 线性时间 内与输入的大小一起运行。 (我必须承认我并不完全理解 Knuth 的算法——只知道它非常聪明。)

【讨论】:

    【解决方案3】:

    动态编程并不是真正的“编程”,而是表查找 [和存储] - 这是牺牲一点空间来提高时间复杂度 [相当多]。

    【讨论】:

      【解决方案4】:

      我知道这是一篇旧帖子,但我有同样的问题,所以我在这里回答自己。

      动态规划有两个属性:

      1. 最优子结构:通过结合局部子问题的最优解可以找到全局最优解。例如,fib(x) = fib(x - 1) + fib(x - 2)
      2. 重叠子问题:找到最优解 涉及多次解决同一个问题。例如,在斐波那契数列中多次计算 fib(x)

      通过上面的定义/属性,不清楚某些问题是否像“一个元素是否属于一个集合”?或者“如何求集合之和”可以归类为动态规划?我可以将集合划分为子集(全局求解)并将其相加(获得全局答案)。另外,在子集中,我做了很多次求和。

      我在一本书中找到了一段,我认为它提供了非常有用的提示来区分“动态编程”(DP)和“分治算法”(D&C)。

      1. 在 D&C 子问题中,它们比原始问题要小得多。相比之下,DP 涉及解决的问题仅比原始问题略小。例如,计算 Fib(19) 的问题并不比计算 Fib(20) 小很多。而计算十个元素的总和远小于一千万个元素的总和。

      2. D&C 算法的效率不取决于算法的结构,以便重复解决相同的问题。相反,只有当不同子问题的数量明显小于子问题的总数时,DP 才有效。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-04-02
        • 1970-01-01
        • 2012-06-13
        • 2011-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多