我很难理解动态编程示例中使用的这种递归。任何人都可以解释这个的工作。目标是找到一个值的最少数量的硬币。
所有denomimations的// f(n)= 1 + min f(n-d)
伪代码:
int memo[128]; //initialized to -1
int min_coin(int n)
{
if(n < 0) return INF;
if(n == 0) return 0;
if(memo[n] != -1)
int ans = INF;
for(int i = 0; i < num_denomination; ++i)
{
ans = min(ans, min_coin(n - denominations[i]));
}
return memo[n] = ans+1; //when does this get called?
}
答案 0 :(得分:1)
这个特殊的例子在Topcoder的article中得到了很好的解释。
基本上,这种递归使用小问题的解决方案(较小n的硬币数量最少)找到整体问题的解决方案。动态编程方面是子问题解决方案的memoization,因此不必每次都重新计算。
是的 - 在他的评论中提到的ring0缺少{} - 只有在以前没有解决子问题时才应该执行递归。
答案 1 :(得分:1)
回答所有者的问题什么时候被调用?:在基于递归程序的解决方案中,相同的函数本身被调用...但最终返回...什么时候返回?从功能停止自称为
f(a) {
if (a > 0) f(a-1);
display "x"
}
f(5);
f(5)
将调用f(4),依次调用f(3)调用f(2)调用f(1)调用f(0)。
f(0)
a
为0,因此不会调用f()
,并显示“x”,然后返回。它返回上一个f(1)
,在调用f(0)
- 完成后 - 也显示“x”。 f(1)
结束,f(2)显示“x”,......,直到f(5)。你得到6“x”。
答案 2 :(得分:0)
在另一个术语中,来自ring0已经提到过 - 当程序到达基本情况并开始通过向上堆栈(调用帧)展开。对于使用factorial example see this.
的类似情况#!/usr/bin/env perl
use strict;
use IO::Handle;
use Carp qw(cluck);
STDOUT->autoflush(1);
STDERR->autoflush(1);
sub factorial {
my $v = shift;
dummy_func();
return 1 if $v == 1;
print "Variable v value: $v and it's address:", \$v, "\ncurrent sub factorial addr:", \&factorial, "\n","-"x40;
return $v * factorial($v - 1);
}
sub dummy_func {
cluck;
}
factorial(5);