跳台阶

题目 跳台阶

image-a828fa79

思路分析

对于任意一个台阶级数 都可以分为由它-1级走一步到达 由它-2级走两步到达

比如 七级台阶可以分成6级台阶走一步 5级台阶走两步 然后再递归处理6级和5级的情况

由此生成这样一棵递归搜索树

image-e8f38227

最小状态 2级台阶有两种走法(0走两次1步 和 0走一次两步) 1级台阶只有一种走法(0走一步)

递归的解法就这样出来了

然后也如上图所示

很多地方都做了没意义的重复操作

image-2da4e728

发现其实只需要算最左边的那条分支 可以得到6 5 4 3 的方法数 把它们记录下来的话 右边就不需要做那么多递归操作了

image-ca5c52ce

直接简化成了近logn的复杂度

这就是记忆化搜索 用一个数组 记录一下每个节点的答案 再遇到相同节点时 直接取即可

接下来还能怎么优化

可以发现我们得到答案只是归的时候得到 和递并没有关系

能否省略从上往下递的步骤 直接由下而上的推出答案

(先把一个一个小问题解决 再解决由他们状态得到的母问题)

再优化的话就是空间上了

发现其实每一个后状态只需要它的前面一个状态和前面两个状态 其他的其实没必要存下来

那么 就可以用滚动数组的思路

因为这里已经是一维了 那么就可以优化成0维 用两个变量交替滚动覆盖

这是一道dp的典型题 由递归优化到记忆化搜索优化到简单的dp(递推)再使用滚动数组优化

也不难发现 dp就是将递归的递过程优化掉 从下而上地分析出答案 在这个过程中 又利用了记忆化的方式 潜在地剪去了很多不必要的分支 (一直都在做 得出答案 又同时微妙的省去了不必要的操作 我想这就叫做动态规划吧 妙)

代码实现

递归

#include<bits/stdc++.h>

using namespace std;

int n;

int dfs(int x)

{

    //1 2是不可再分的 所以直接返回

    if(x==1)

        return 1;

    else if(x==2)

        return 2;

    //对于其他情况就可以一直拆解递归

    else

        return dfs(x-1)+dfs(x-2);

}

int main()

{

    cin>>n;

    int res=dfs(n);

    cout<<res;

    return 0;

}

记忆化搜索

#include<bits/stdc++.h>

using namespace std;

const int N=20;

int mem[N];//新增记忆化数组

int n;

int dfs(int x)

{

    //若已存过 就返回记录的结果

    if(mem[x])

        return mem[x];

    int sum=0;

    if(x==1)

        sum = 1;

    else if(x==2)

        sum = 2;

    else

        sum=dfs(x-1)+dfs(x-2);

    mem[x]=sum;

    return sum;

}

int main()

{

    cin>>n;

    int res=dfs(n);

    cout<<res;

    return 0;

}

递推(dp)

#include<bits/stdc++.h>

using namespace std;

const int N=20;

int dp[N];

int n;

int main()

{

    cin>>n;

    dp[1]=1,dp[2]=2;

    //把dfs的归部分 状态转移 成这样的递推公式

    for(int i=3;i<=n;i++)

        dp[i]=dp[i-1]+dp[i-2];

    cout<<dp[n];

    return 0;

}

滚动优化

#include<bits/stdc++.h>

using namespace std;

int n;

int main()

{

    cin>>n;

    int a,b,fn;

    a=1,b=2;

    for(int i=1;i<=n;i++)

    {

        if(i==n)

            cout<<a;

        fn=a+b;

        a=b,b=fn;

    }

    return 0;

}

同类题型

视频讲解


⬅️ 背包问题求方案数 🏠 00-刷题理模型 ➡️ 中位 平均