P1255 数楼梯

数楼梯

 题目描述

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

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

输入格式

一个数字,楼梯数。

 输出格式

输出走的方式总数。

 样例 1

 样例输入 1
4

 样例输出 1
5

说明/提示

  • 对于 60%的数据,𝑁≤50;
  • 对于 100% 的数据,1≤𝑁≤5000。

解题思路

  1. 考虑边界情况
    • 如果n等于1,直接返回1,因为数列的第一项就是1。
    • 如果n等于2,直接返回2,因为数列的第二项就是2。
  2. 使用动态规划求解
    • 创建一个数组dp,用于存储斐波那契数列的每一项。
    • 初始化dp数组的前两项为1和2。
    • 从第三项开始,使用循环计算每一项的值。每一项的值都是前两项的和,可以使用高精度加法函数add来计算。
    • 循环直到计算出第n项的值。
  3. 高精度加法函数
    • 定义一个高精度加法函数add,用于计算两个大数的和。
    • 使用字符串来表示大数,从字符串的末尾开始逐位相加,同时考虑进位。
    • 将每一位的和的个位数添加到结果字符串中,并更新进位。
    • 反转结果字符串,因为是从末尾开始计算的。
    • 返回结果字符串。
  4. 输出结果
    • 计算完成后,输出dp数组的第n项作为结果。

总结:

  • 该问题是一个典型的斐波那契数列问题,可以通过动态规划求解。
  • 由于n可能很大,需要使用高精度加法来处理大数相加的情况。
  • 边界情况需要单独处理。
  • 最后输出第n项的值作为结果。

示例代码

#include <iostream>    
#include <string>    
#include <algorithm>    
    
using namespace std;    
    
// 高精度加法函数,用于计算两个大数的和  
string add(const string &a, const string &b) {    
    string result;  // 存储结果的字符串  
    int carry = 0;  // 进位  
    int sum = 0;    // 临时存储每一位的和  
    int i = a.size() - 1;  // a字符串的索引  
    int j = b.size() - 1;  // b字符串的索引  
    
    // 从后往前遍历两个字符串,直到遍历完或者没有进位  
    while (i >= 0 || j >= 0 || carry > 0) {    
        sum = carry;  // 先加上进位  
        if (i >= 0) sum += a[i] - '0';  // 如果a没遍历完,加上a的当前位  
        if (j >= 0) sum += b[j] - '0';  // 如果b没遍历完,加上b的当前位  
        carry = sum / 10;  // 计算新的进位  
        result.push_back(sum % 10 + '0');  // 将当前位的值加到结果字符串中  
        i--;    
        j--;    
    }    
    
    reverse(result.begin(), result.end());  // 反转结果字符串,因为我们是从后往前计算的  
    return result;    
}    
    
int main() {    
    int n;    
    cin >> n;  // 输入n  
    
    // 斐波那契数列的前两项  
    if (n == 1) {    
        cout << "1" << endl;    
        return 0;    
    }    
    
    if (n == 2) {    
        cout << "2" << endl;    
        return 0;    
    }    
    
    string dp[n + 1];  // 动态规划数组,用于存储斐波那契数列的每一项  
    dp[1] = "1";  // 初始化第一项  
    dp[2] = "2";  // 初始化第二项  
    
    // 从第三项开始,每一项都是前两项的和  
    for (int i = 3; i <= n; i++) {    
        dp[i] = add(dp[i - 1], dp[i - 2]);    
    }    
    
    cout << dp[n] << endl;  // 输出第n项  
    
    return 0;    
}

  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值