【发布时间】:2020-09-30 07:09:43
【问题描述】:
我大多听说如果你可以制作递归代码,你可以将它转换为动态编程代码,但有什么必要这样做呢?以及如何将递归代码转换为DP?
【问题讨论】:
标签: recursion dynamic-programming
我大多听说如果你可以制作递归代码,你可以将它转换为动态编程代码,但有什么必要这样做呢?以及如何将递归代码转换为DP?
【问题讨论】:
标签: recursion dynamic-programming
在动态规划中,有 2 种方法,自上而下和自下而上。
让我们以斐波那契数列为例:
f(0) = 0 : x = 1,
f(1) = 1 : x = 1,
f(x) = f(x-1) + f(x-2) : x > 1
自上而下的方法:
它使用递归+记忆(存储计算状态以避免重新计算):
int memo[1000];//initialized by zeroes
int f(int x) {
if (x == 0 || x == 1) return 1;
if (memo[x] != 0) return memo[x]; //trying to avoid recalculation
memo[x] = f(x - 1) + f(x - 2); //storing the result
return memo[x];
}
正如您在此处注意到的,计算 f(x) 值时,我们必须将其分解为
f(x-1) 和 f(x-2),这就是它被称为自上而下的原因。
自下而上的方法:
它使用循环(for,while...)而不是递归并将值存储在数组中:
int memo[1000];
int bottom_up(int x) {
memo[0] = 1;
memo[1] = 1;
for (int i = 2; i < 1000; i++)
memo[i] = memo[i - 1] + memo[i - 2];
}
如您所见,我们计算斐波那契数列的值是从较小的值到较大的值,这就是它被称为自下而上的原因。
将代码从递归转换为循环被视为将递归代码转换为迭代代码。
递归代码会多次调用自己,你应该知道每个函数调用都会存储在你的内存堆栈中,所以最好使用迭代方法,因为它对内存和性能会更好。
【讨论】: