动态编程 - 自上而下与自下而上

时间:2013-09-29 22:46:08

标签: recursion dynamic-programming memoization bottom-up top-down

我学到的是动态编程(DP)有两种:自上而下和自下而上。

自上而下中,您可以使用递归和memoization。在自下而上中,您只需填充数组(表格)。

此外,这两种方法都使用相同的时间复杂度。就个人而言,我发现自上而下的方法更容易和自然地遵循。是否可以使用任何一种方法解决DP的特定问题?或者我会遇到一个只能通过两种方法之一解决的问题吗?

2 个答案:

答案 0 :(得分:1)

我相信理论上你应该能够用任何一种方法解决DP问题。但是,有些情况下,自下而上的方法可能变得过于昂贵。考虑knapsack_size = 200,000num_items = 2000的背包问题。用ints填充二维DP表是不可能的。你将耗尽普通电脑的主存。此外,您不需要填写表中的所有条目以实现所需的最终计算。在这种情况下,递归自上而下的方法要好得多。希望能帮助到你。

答案 1 :(得分:0)

自下而上的DP要求您查看递归如何精确地构建完整的解决方案,即正在创建什么样的子问题,如何用基本情况来填充它们,因此在编写自下而上的动态编程时有些困难自上而下必须编写一个回溯解决方案(仍然很难想到),然后查看回溯解决方案的状态。状态表示递归函数的参数在随后的递归调用中有所不同。

现在是时间上的复杂性:
自下而上的DP比自上而下的速度更快,因为它不涉及任何函数调用。它完全取决于表条目,而在自上而下的DP中,它需要函数调用,从而导致隐式的堆栈形成。

PS:要了解自上而下和自下而上的时间复杂性之间的差异,您需要解决SPOJ上的ASSIGNMENTS问题。