【洛谷 P1255】数楼梯 题解(递归+记忆化搜索+高精度)

简介: 这是一个使用动态规划解决的“数楼梯”问题。给定楼梯数`N`,求不同上楼方式的数量。程序通过递归函数`f()`计算,其中`f(x) = f(x - 1) + f(x - 2)`,初始条件`f(1) = 1`,`f(2) = 2`。考虑到数据规模可能很大,使用了高精度加法运算。样例输入`4`,输出`5`。代码中定义了一个存储中间结果的向量`mem`,并提供了一个用于显示高精度数的`printv()`函数。

数楼梯

题目描述

楼梯有 $N$ 阶,上楼可以一步上一阶,也可以一步上二阶。

编一个程序,计算共有多少种不同的走法。

输入格式

一个数字,楼梯数。

输出格式

输出走的方式总数。

样例 #1

样例输入 #1

4

样例输出 #1

5

提示

  • 对于 $60\%$ 的数据,$N \leq 50$;
  • 对于 $100\%$ 的数据,$1 \le N \leq 5000$。

思路

f(x) = f(x - 1) + f(x - 2)
f(1) = 1;f(2) = 2
数据过大,long long不够大,必须上高精度。

AC代码

#include <iostream>
#include <vector>
#define AUTHOR "HEX9CF"
using namespace std;

const int maxn = 10005;

long long n;
vector<int> mem[maxn];

vector<int> add(vector<int> v1, vector<int> v2)
{
   
    vector<int> v3;
    vector<int>::iterator it1 = v1.begin();
    vector<int>::iterator it2 = v2.begin();
    for (; it1 != v1.end() && it2 != v2.end(); it1++, it2++)
    {
   
        int sum = *it1 + *it2;
        v3.push_back(sum);
    }
    for (; it1 != v1.end(); it1++)
    {
   
        v3.push_back(*it1);
    }
    for (; it2 != v2.end(); it2++)
    {
   
        v3.push_back(*it2);
    }
    vector<int>::iterator it3 = v3.begin();
    int flg = 0;
    for (; it3 != v3.end(); it3++)
    {
   
        if (*it3 > 9)
        {
   
            *it3 -= 10;
            if (it3 + 1 == v3.end())
            {
   
                flg = 1;
            }
            else
            {
   
                *(it3 + 1) += 1;
            }
        }
    }
    if (flg)
    {
   
        v3.push_back(1);
    }
    return v3;
}

void printv(vector<int> v)
{
   
    vector<int>::reverse_iterator rit = v.rbegin();
    for (; rit != v.rend(); rit++)
    {
   
        cout << *rit;
    }
    cout << endl;
}

void f(long long x)
{
   
    if(!mem[x].empty()){
   
        return;
    }
    if (x < 3)
    {
   
        mem[x].push_back(x);
        return;
    }
    f(x - 1);
    f(x - 2);
    mem[x] = add(mem[x - 1], mem[x - 2]);
}

int main()
{
   
    cin >> n;
    f(n);
    printv(mem[n]);
    return 0;
}
目录
相关文章
|
数据采集 自然语言处理 搜索推荐
图文详解 DFS 和 BFS | 算法必看系列知识二十四
深度优先遍历(Depth First Search, 简称 DFS) 与广度优先遍历(Breath First Search)是图论中两种非常重要的算法,生产上广泛用于拓扑排序,寻路(走迷宫),搜索引擎,爬虫等,也频繁出现在高频面试题中。
35693 6
图文详解 DFS 和 BFS | 算法必看系列知识二十四
|
5月前
|
存储 网络协议 数据安全/隐私保护
SMTP/POP3/IMAP(电子邮件协议)
本文介绍了电子邮件系统中常用的三种协议:SMTP、POP3 和 IMAP。SMTP(简单邮件传输协议)用于发送邮件,设计简单且广泛支持;POP3(邮局协议版本3)用于接收邮件,适合离线使用但不支持文件夹管理;IMAP(互联网消息访问协议)允许用户在服务器上管理邮件,支持多设备同步和部分下载。文章还对比了这三种协议的功能、端口及特点,并分析了它们在实际场景中的应用,帮助用户根据需求选择合适的协议。
1605 24
|
存储 物联网
【洛谷 P1135】奇怪的电梯 题解(广度优先搜索)
这是一个关于奇怪电梯的编程问题摘要: - 电梯在每层停,且每层有特定数字 $K_i$ 决定上/下按钮的功能。 - 目标是从 $A$ 楼到 $B$ 楼,求最少按键次数,若无法到达则输出 `-1`。 - 输入包括 $N$(楼层数)、$A$(起点)和 $B$(终点),以及每层的 $K_i$ 数字。 - 使用广度优先搜索(BFS)解决,通过队列存储访问过的楼层,避免重复并计算步数。 - 当到达目标楼层时返回步数,队列空时返回 `-1`。
261 0
|
存储 算法 Java
【DFS(深度优先搜索)详解】看这一篇就够啦
本文介绍了深度优先搜索(DFS)算法及其应用。DFS从某个顶点出发,深入探索图的每条路径,直到无法前进为止,然后回溯。文章详细解释了DFS的基本思想,并通过示例图展示了其执行过程。此外,文中还探讨了三种枚举方式:指数型枚举、排列型枚举和组合型枚举,并提供了具体的代码实现。最后,文章通过几道练习题帮助读者更好地理解和应用DFS算法。
8796 19
【DFS(深度优先搜索)详解】看这一篇就够啦
|
XML Java 应用服务中间件
Tomcat_servlet部署、编译、配置、打包
Tomcat_servlet部署、编译、配置、打包
244 0
|
Java BI 程序员
「软件项目管理」成本估算模型——Walston-Felix模型和COCOMO Ⅱ模型
该文章深入探讨了两种软件项目成本估算模型——Walston-Felix模型和COCOMO II模型,详细解释了各自的计算公式、应用背景及步骤,并通过具体示例展示了如何使用这两种模型来进行准确的成本预测。
「软件项目管理」成本估算模型——Walston-Felix模型和COCOMO Ⅱ模型
|
存储 Java
【数据结构】二叉树的三种遍历(非递归讲解)
【数据结构】二叉树的三种遍历(非递归讲解)
175 1
|
算法 定位技术
探寻最短路径之谜:Dijkstra算法详解
探寻最短路径之谜:Dijkstra算法详解
|
前端开发 Java
SpringBoot之三层架构的详细解析
SpringBoot之三层架构的详细解析
3324 0