首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >逼近动态规划

逼近动态规划
EN

Stack Overflow用户
提问于 2014-11-18 07:45:32
回答 2查看 8.3K关注 0票数 5

我用动态规划技术编写了一个计算数字阶乘的小程序。

代码语言:javascript
复制
#include<stdio.h>

int fact(int n)
{
    int f[n],i;
    f[0] = 1;

    for(i=1;i<=n;i++)
        f[i] = i * f[i-1];
    return f[n];
}

int main(void)
{
    printf("\n Factorial of %d is %d ",5,fact(5));
    return 0;
}

记忆的方法正确吗?因为动态规划涉及递归。但我还没有把它包括在这里。所以我不确定我的方法。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-11-18 08:12:06

是的,这是动态规划:从基本案例到最终案例。当然,您的示例(阶乘)太简单了,所以您可以自己简化许多事情:您消除了递归,并且从未在回忆录中使用测试。但不管怎么说就是这样。

关于回忆录的总体方案,见http://en.wikipedia.org/wiki/Memoization

有关动态编程的说明,请参阅programming,您将能够阅读关于Fibonacci序列及其使用自下而上方法计算的部分。

票数 2
EN

Stack Overflow用户

发布于 2016-01-20 14:05:29

是的,您解决问题的方法是一个非常简单的动态规划案例,您可以存储以前解决过的子问题,以帮助您解决实际问题。虽然您提供的示例将被视为动态编程,但它通常不被称为回溯

当有人说“回溯”()时,它通常涉及到自上而下的解决问题的方法,在这种方法中,您假设您已经通过以解决子问题的方式构造程序来解决了子问题。您可以存储这些子问题的结果,或者回忆录,这样它们就不会被多次计算。

让我通过一个例子来说明回溯

下面是一个计算数字的第n个斐波纳契的简单例子:

代码语言:javascript
复制
int fib(int n)
{
   if (n <= 1)
      return n;
   return fib(n-1) + fib(n-2);
}

上面的代码使用递归来求解sub-problems (fib(n-1)和fib(n-2)),从而最终可以求解fib(n)。它假设fib(n-1)和fib(n-2)已经以结构化的方式解决了。

虽然这段代码看起来很优雅,但运行时间却是指数级的,因为您可以多次求解fib(i),其中i小于n。您可以查看这里提供的图表,查看由这个问题生成的树:http://www.geeksforgeeks.org/program-for-nth-fibonacci-number

为了避免不必要的重计算,使用记忆对运行时进行内存优化.

下面是使用Memoization:计算第n个斐波纳契数的优化示例

代码语言:javascript
复制
/*Global array initialized to 0*/
int a[100];

int fib(int n)
{
    /*base case*/
    if (n <= 1) 
        return n;
    /*if fib(n) has not been computed, compute it*/
    if (a[n] == 0) {
        a[n] = fib(n - 1) + fib(n - 2);
    }
    */Otherwise, simply get a[n] and return it*/
    return a[n];
}  

正如您所看到的,总体结构与递归解没有太大的不同,但是它运行的是线性时间而不是指数时间,因为只有在我们还没有计算的情况下才会计算fib(i)。

如果我使用您的方法,Dynamic Programming来解决Fibonacci问题,它应该如下所示:

代码语言:javascript
复制
 int fib(int n)
 {
   /* just like the array you declared in your solution */
   int f[n+1];
   int i;

   /* set up the base cases, just like how you set f[0] to 1*/
  f[0] = 0;
  f[1] = 1;

   for (i = 2; i <= n; i++)
   {
       /* using previously solved problem to solve further problems*/
       f[i] = f[i-1] + f[i-2];
   }
     /*return the final result*/
   return f[n];
}

动态规划和记忆之间有更微妙的区别、权衡和暗示。有些人认为记忆是动态规划的一个子集。你可以在这里读到更多关于不同之处的内容:

Dynamic programming and memoization: bottom-up vs top-down approaches

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26989075

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档