问题描述
小U最近决定挑战一座非常高的楼梯,每次他可以选择走一步或两步,但有一个重要的限制:他不能连续走两步。因此,小U想知道他总共有多少种不同的方式可以从楼梯的底部走到顶端。
你需要帮他计算在给定的楼梯层数下,小U有多少种走法。
测试样例
样例1:
输入:
n = 2输出:2
样例2:
输入:
n = 3输出:3
样例3:
输入:
n = 4输出:4
解题思路
-
理解问题:小U每次可以选择走一步或两步,但不能连续走两步。这意味着在每一步之后,他必须选择走一步,然后再决定下一步是走一步还是两步。
-
动态规划:我们可以使用动态规划来解决这个问题。定义两个状态:
dp[i][0]:表示到达第i层时,最后一步是走一步的走法数。dp[i][1]:表示到达第i层时,最后一步是走两步的走法数。
-
状态转移方程:
dp[i][0] = dp[i-1][0] + dp[i-1][1]:到达第i层且最后一步是走一步的走法数,等于到达第i-1层且最后一步是走一步或两步的走法数之和。dp[i][1] = dp[i-2][0]:到达第i层且最后一步是走两步的走法数,等于到达第i-2层且最后一步是走一步的走法数。
-
初始条件:
dp[1][0] = 1:到达第1层且最后一步是走一步的走法数为1。dp[1][1] = 0:到达第1层且最后一步是走两步的走法数为0。dp[2][0] = 1:到达第2层且最后一步是走一步的走法数为1。dp[2][1] = 1:到达第2层且最后一步是走两步的走法数为1。
-
答案:
dp[n][0] + dp[n][1]即为到达第n层的总走法数。
code
#include <iostream>
int solution(int n) {
int dp[200][2];
dp[0][0] = 0;
dp[0][1] = 0;
dp[1][0] = 1;
dp[1][1] = 0;
dp[2][0] = 1;
dp[2][1] = 1;
for (int i = 3; i <= n; ++i) {
dp[i][0] = dp[i - 1][0] + dp[i - 1][1];
dp[i][1] = dp[i - 2][0];
}
return dp[n][0] + dp[n][1];
}
int main() {
// Add your test cases here
std::cout << (solution(2) == 2) << std::endl;
return 0;
}