动态规划浅析篇

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_22520215/article/details/79068746

先上题目:

小时候我们都跳过方格游戏吧!现在规定一次只能向前跳1格或2格,不能后退,要想正好跳到第10格,有多少种跳法?

一、暴力枚举

程序我就不写了,因为嵌套循环太多,时间复杂度高。

二、我们假设跳到n格有F(n)种可能;

我们来思考,我跳一次有几种可能,很简单,跳一次我有2种可能,1格或者2格;同理,我最后一次跳到第n格有几种可能?当然2种,比如我跳一次到第5个格的可能有从4格跳到5格或从3个跳到5格2种可能,而总的方法就等于跳到第4格和跳到第3格方法的总和。

其实上面是一种递归的思想;F(10) = F(9) + F(8)  F(9) = F(8) + F(7)  ...........

即F(n) = F(n-1) + F(n-2)

所以我们可以用递归实现:

int GetNum(int n)
{
    if(n==1) return 1;
    if(n==2) return 2;
    return (GetNum(n-1) + GetNum(n-2));
}
 三、第二方法中的时间复杂度为O(2^n),仔细分析复杂度高是因为在递归时重复了一些值的运算,导致时间复杂度的增加;所以为了减少重复计算,我们建立一个备忘录来记录已经计算过的值,则时间复杂度变为O(n),但空间复杂度为O(n); 
 

int GetNum(int n)
{
    if(n==1) return 1;
    if(n==2) return 2;
    if(map.text(n))
    {
        return map.get(n);
    }else 
    {
        int Value=(GetNum(n-1) + GetNum(n-2));
        map.put(n,Value);
        return Value
     }
}
四、那有没有更好的办法,让空间复杂度更低,甚至为O(1)呢?哈哈 下面就是今天的重点,动态规划!

我们不妨把思路逆过来!这样我们走到第n格就只依赖于n-1和n-2格的方法,所以我们只要保持前2个状态的方法就可以迭代出当前的方法。所以我们需要建立2个临时变量;这样增加2个变量反而空间复杂度变为O(1)了。

程序如下:

int GetNum(int n)
{
   if(n==1) return 1;
   if(n==2) return 2;
   int a =1,b=2,temp=0,i;
  
   for(i = 3;i<=n; i++)
   {
      temp = a+b;
      a=b;
      b=temp;
    }
}


这是对动态规划最基本的了解!要想真正测试自己懂了没,要看下一篇动态规划进阶篇,那道题会了才是真会了!


猜你喜欢

转载自blog.csdn.net/qq_22520215/article/details/79068746