数楼梯
题目描述
楼梯有 阶,上楼可以一步上一阶,也可以一步上二阶。
编一个程序,计算共有多少种不同的走法。
输入格式
一个数字,楼梯数。
输出格式
输出走的方式总数。
样例 1
样例输入 1
4
样例输出 1
5
说明/提示
- 对于 60%的数据,𝑁≤50;
- 对于 100% 的数据,1≤𝑁≤5000。
解题思路
- 考虑边界情况:
- 如果n等于1,直接返回1,因为数列的第一项就是1。
- 如果n等于2,直接返回2,因为数列的第二项就是2。
- 使用动态规划求解:
- 创建一个数组dp,用于存储斐波那契数列的每一项。
- 初始化dp数组的前两项为1和2。
- 从第三项开始,使用循环计算每一项的值。每一项的值都是前两项的和,可以使用高精度加法函数add来计算。
- 循环直到计算出第n项的值。
- 高精度加法函数:
- 定义一个高精度加法函数add,用于计算两个大数的和。
- 使用字符串来表示大数,从字符串的末尾开始逐位相加,同时考虑进位。
- 将每一位的和的个位数添加到结果字符串中,并更新进位。
- 反转结果字符串,因为是从末尾开始计算的。
- 返回结果字符串。
- 输出结果:
- 计算完成后,输出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;
}