通过把所计算的值存储在递归过程的外部数组中,明确地避免重复计算。这一程序计算的时间与N成正比。
int F(int i)
{
if(knownF[i] != unknown)
return knownF[i];
if(i == 0) t = 0;
if(i == 1) t = 1;
if(i > 1) t = F(i - 1) + F(i - 2);
return knownF[i] = t;
}
性质:动态规划降低了递归函数的运行时间,也就是减少了计算所有小于或等于给定参数的递归调用所要求的时间,其中处理一次递归调用的时间为常量。
我们不需要把递归参数限制到单整形参数的情况。当有一个带有多个整形参数的函数时,可以把较小子问题的解存储在多维数组中,一个参数对应数组的一维。其他那些完全不涉及整形参数的情形,就使用抽象的离散问题公式,它能让我们把问题分解为一个个的小问题。
在自顶向下的动态规划中,我们存储已知的值;在自底向上的动态规划中,我们预先计算这些值。我们常常选择自顶向下的动态规划而不选自底向上动态规划,其原因如下:
1 自顶向下的动态规划是一个自然的求解问题的机械转化。
2 计算子问题的顺序能自己处理。
3 我们可能不需要计算所有子问题的解。
我们不能忽视至关重要的一点是,当我们需要的可能的函数值的数目太大以至于不能存储(自顶向下)或预先计算(自底向上)所有值时,动态规划就会变得低效。自顶向下动态规划确实是开发高效的递归算法实现的基本技术,这类算法应纳入任何从事算法设计与实现所需的工具箱。