【AcWing刷题】蓝桥杯专题突破-动态规划-dp入门(17)

简介: 【AcWing刷题】蓝桥杯专题突破-动态规划-dp入门(17)

写在前面:

怎么样才能学好一个算法?


我个人认为,系统性的刷题尤为重要,


所以,为了学好动态规划,应对 “DP杯”。


事不宜迟,我们即刻开始刷题!


题目:821. 跳台阶 - AcWing题库

题目描述:

一个楼梯共有 n 级台阶,每次可以走一级或者两级,


问从第 0 级台阶走到第 n 级台阶一共有多少种方案。


输入格式:

共一行,包含一个整数 n。


输出格式:

共一行,包含一个整数,表示方案数。


数据范围:

1 ≤ n ≤ 15


输入样例:

5

输出样例:

8

解题思路:

这道题是一道经典的dp入门题目,


我打算使用三种方法去做,层层推进,一起入门递归:


方法一:暴力搜索

这道题在之前dfs的刷题中也有出现,


我们可以用dfs搜索所有的方案:



跳三级台阶就是跳两级台阶的方法+跳一级台阶的方法;


跳四级台阶就是跳三级台阶的方法+跳二级台阶的方法;


以此类推:


最后得出答案:


代码如下:


代码

#include 
#include 
#include 
#include 
using namespace std;
int n = 0;
int dfs(int u)
{
    if(u == 1) return 1;
    else if(u == 2) return 2;
    return dfs(u - 1) + dfs(u - 2);
}
int main()
{
    scanf("%d", &n);
    int res = dfs(n);
    printf("%d", res);
    return 0;
}


方法二:记忆化搜索

实际上第一种方法的时间复杂度太高,


有2的n次方那么大:


如果n >= 42,就会超时:


为了减少时间的消耗,我们可以用记忆化搜索:


将已经求过的值记录到一个数组中,


这样搜索过的值就不用重复搜索:



下面是代码实现:


代码

#include 
#include 
#include 
#include 
using namespace std;
int n = 0;
int sum = 0;
const int N = 30;
int mem[N];//用一个数组记录
int dfs(int u)
{
    if(mem[u]) return mem[u];//如果记录过,就不用往下搜索了
    if(u == 1) return 1;
    else if(u == 2) return 2;
    else sum = dfs(u - 1) + dfs(u - 2);
    mem[u] = sum;//将该位置的值记录进数组
    return mem[u];
}
int main()
{
    scanf("%d", &n);
    int res = dfs(n);
    printf("%d", res);
    return 0;
}


我们发现这样之后,就算n = 100,也只需要1ms:



方法三:动态规划

我们发现,其实这道题动态规划的


状态表达式就是由暴力搜索推出来的,


递归搜索是从上往下搜索,


再从下往上回溯,


其实得出的结果的过程就是在回溯的时候:


那我们可以不用搜索这个过程,直接从下往上递推,


这就是动态规划:



下面是代码实现:


代码

#include 
#include 
#include 
#include 
using namespace std;
int n = 0;
const int N = 30;
int fib[N];
int main()
{
    scanf("%d", &n);
    fib[1] = 1;
    fib[2] = 2;
    if(n == 1 || n == 2)
    {
        printf("%d", fib[n]);
        return 0;
    }
    for(int i = 3; i <= n; i++)
    {
        //这个就是动态规划的状态表达式
        fib[i] = fib[i - 1] + fib[i - 2];
    }
    printf("%d", fib[n]);
    return 0;
}

AC !!!!!!!!!!


写在最后:

以上就是本篇文章的内容了,感谢你的阅读。


如果喜欢本文的话,欢迎点赞和评论,写下你的见解。


如果想和我一起学习编程,不妨点个关注,我们一起学习,一同成长。


之后我还会输出更多高质量内容,欢迎收看。


相关文章
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-dp练习3
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-dp练习3
163 0
|
11月前
|
算法
蓝桥杯16天刷题计划一一Day02
这是蓝桥杯16天刷题计划的第二天内容,由作者blue于2025年3月28日整理。当天训练重点为二分法,包含多道经典题目解析与代码实现,如有序数组查找、砍树问题、木材加工等。文章针对二分法的应用场景进行了深入讲解,并通过实例演示了如何优化算法效率,适合对二分法不熟悉的初学者学习和练习。
272 5
|
Python
蓝桥杯练习题(一):Python组之入门训练题
这篇文章是关于蓝桥杯Python组的入门训练题,包括Fibonacci数列、圆的面积、序列求和和A+B问题的具体代码实现和样例输出。
386 0
|
算法 测试技术 C++
【动态规划算法】蓝桥杯填充问题(C/C++)
【动态规划算法】蓝桥杯填充问题(C/C++)
|
11月前
|
存储 自然语言处理 算法
蓝桥杯16天刷题计划一一Day01(STL练习)
本文介绍了蓝桥杯16天刷题计划的第一天内容,主要练习STL相关算法。涵盖队列、优先队列、单调队列、单调栈和链表等数据结构的应用。通过经典题目如机器翻译(队列模拟内存)、约瑟夫问题(链表模拟报数)、滑动窗口(单调队列)、Look Up(单调栈)、合并果子(优先队列)和最小函数值(优先队列结构体排序),详细解析了每种数据结构的实现与优化方法,并附有完整代码示例。适合初学者掌握STL核心用法及算法思想。
313 10
|
算法 Java C++
【潜意识Java】蓝桥杯算法有关的动态规划求解背包问题
本文介绍了经典的0/1背包问题及其动态规划解法。
463 5
蓝桥杯-动态规划专题-子数组系列,双指针
蓝桥杯-动态规划专题-子数组系列,双指针
蓝桥杯动态规划-第五弹 最大子数组和 买卖股票最佳时机IV 第N个泰波那契数 环形数组
蓝桥杯动态规划-第五弹 最大子数组和 买卖股票最佳时机IV 第N个泰波那契数 环形数组