问题描述
爬楼梯
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
示例 1:
输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
- 1 阶 + 1 阶
- 2 阶
示例 2:
输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
- 1 阶 + 1 阶 + 1 阶
- 1 阶 + 2 阶
- 2 阶 + 1 阶
https://leetcode-cn.com/explore/interview/card/top-interview-questions-easy/23/dynamic-programming/54/
题干解读
首先判断这是一道使用动态规划的题目
为什么?
一道可以使用动态规划的题目应满足以下三要素:
1.最优子结构:最优子结构是指每个阶段的最优状态可以从之前某个阶段的某个或某些状态直接得到(子问题的最优解能够决定这个问题的最优解)
在该题目中设n阶台阶有F(n)种方法,则必然有F(n)=F(n-1)+F(n-2),即每一阶段的解可以有前两个阶段的解直接得到。
2.边界:边界指的是问题最小子集的解(即初始范围)
此题中有最初阶段的解为F(1)与F(2),即可以此为基础进行递归运算
3.状态转移函数:这个最好理解,是指从一个阶段向另一个阶段过度的具体形式,描述的是两个相邻子问题之间的关系,即可以直观表达为递推函数表达式
至此我们至少可以立马意识到我们需要在代码里做出两件事:
1.初始化F(1)与F(2),这是边界,即初始状态,必须先直接给出
2.用程序语言表达出F(n)=F(n-1)+F(n-2);显然要用到循环结构
下面给出标准答案代码
题解代码
n = int(input()) # 用户输入,一定不要忘记将读入的字符串转化为整型
if n <=2:
F = n;
# 易得当n=1或2时,F(n)=n;
else :
a = 1
b = 2
temp = 0
# 初始化边界和临时变量temp
for i in range(3,n + 1): #使用for循环来表示递推表达式
temp = a + b
a = b # 这里将a后推了一位
b = temp # 这里将b后推了一位
# 通过该循环可以完成递推出F(n)的任务,且存储在了temp中
F = temp
print(F) #输出答案
事实上,这是个通俗易懂的版本,你可能没有很能感受到动态规划的思想在其中,再看下面这一版本
n = int(input())
if n <= 2:
F = n
else:
temp_list = [0, 1, 2]
for i in range(3, n + 1):
temp_list.append(temp_list[-1] + temp_list[-2]) # 将前两项的和加至列表末尾
F = temp_list[-1] # 最后一项即是我们所需的答案
print(F)
到这里,你一定发现了这个问题的本质其实就是斐波那契数列
好哥们看到了点一个赞再走哇