【洛谷 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;
}
目录
相关文章
|
人工智能
【动态规划刷题 11】等差数列划分&& 最长湍流子数组
【动态规划刷题 11】等差数列划分&& 最长湍流子数组
|
5月前
【洛谷】P1102 A-B 数对
洛谷 P1102 A-B 数对
51 0
【洛谷】P1102 A-B 数对
|
6月前
|
Java
贪心 -力扣860.柠檬水找零力扣2208.将数组和减半的最少操作次数力扣179.最大数力扣376.摆动序列
贪心 -力扣860.柠檬水找零力扣2208.将数组和减半的最少操作次数力扣179.最大数力扣376.摆动序列
|
6月前
|
存储
【洛谷 P2437】蜜蜂路线 题解(递归+记忆化搜索+高精度)
蜜蜂路线问题:蜜蜂从蜂房$m$到$n$($m&lt;n$)按数字递增爬行。给定$m$和$n$,求路线数。示例:$m=1$,$n=14$,输出$377$。100%数据$1\leq m,n\leq1000$。使用斐波那契序列优化,高精度处理大数。代码实现斐波那契存储并动态规划求解。
99 0
|
人工智能 算法 C++
洛谷 P1090 合并果子(贪心)
洛谷 P1090 合并果子(贪心)
142 0
|
7月前
【每日一题Day170】LC1040移动石子直到连续 II | 双指针 贪心 数学
【每日一题Day170】LC1040移动石子直到连续 II | 双指针 贪心 数学
58 1
|
7月前
代码随想录Day32 动态规划01 LeetCodeT509 斐波那契数列 T70 爬楼梯 T746 爬楼梯的最小消耗
代码随想录Day32 动态规划01 LeetCodeT509 斐波那契数列 T70 爬楼梯 T746 爬楼梯的最小消耗
50 0
|
7月前
代码随想录Day45 动态规划13 LeetCode T1143最长公共子序列 T1135 不相交的线 T53最大子数组和
代码随想录Day45 动态规划13 LeetCode T1143最长公共子序列 T1135 不相交的线 T53最大子数组和
69 0
|
算法
代码随想录算法训练营第五十三天 | LeetCode 1143. 最长公共子序列、1035. 不相交的线、53. 最大子数组和
代码随想录算法训练营第五十三天 | LeetCode 1143. 最长公共子序列、1035. 不相交的线、53. 最大子数组和
62 1
LeetCode题:70爬楼梯,126斐波那契数
LeetCode题:70爬楼梯,126斐波那契数
59 0