爬楼梯系列篇
爬楼梯
题目简述
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
1 | 示例 1: |
解题思路
动态规划五部曲
- 定义dp[i]:表示踏上第i台阶有dp[i]种方法。
- dp[i-1]表示踏上第i-1台阶有dp[i-1]种方法,那么只要再踏上1步就是第i台阶
- dp[i-2]表示踏上第i-1台阶有dp[i-2]种方法,那么只要再踏上2步就是第i台阶
- 确定dp状态转移方程。
1
dp[i] = dp[i-1] + dp[i-2]
- 初始化dp数组。
- dp[0]表示踏上第0台阶(那就是地面咯),所以dp[0]=1
- dp[1]表示踏上第1台阶,所以dp[1]=1
- 确定for循环长度、顺序、开始位置。
- 遍历长度为n
- 正序遍历
- 开始位置为2
- 举例推导dp数组
代码
1 | public static int test(int n) { |
使用最小花费爬楼梯
给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。
一旦你支付此费用,即可选择向上爬一个或者两个台阶。
你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。
请你计算并返回达到楼梯顶部的最低花费。
1 | 示例 1: |
解题思路
动态规划五部曲:
- 确定dp[i]。dp[i]表示踏上第i台阶最低花费
- dp[i-1]:踏上第i-1台阶最低花费,那么只需要再爬1个台阶即可到达第i台阶,
最低花费dp[i-1]+cost[i-1] - dp[i-2]:踏上第i-2台阶最低花费,要到达到第i台阶则有两种方式:
- 一个一个台阶爬,花费dp[i-2]+cost[i-2]+cost[i-1],这样花费肯定多
- 爬2个台阶,花费dp[i-2]+cost[i-2]
- dp[i-1]:踏上第i-1台阶最低花费,那么只需要再爬1个台阶即可到达第i台阶,
- 确定状态转移方程。求最低花费dp[i],其实就是求dp[i-1]与dp[i-2]+cost[i]最小值
1
dp[i] = min(dp[i-1]+cost[i-1], dp[i-2]+cost[i-2])
- 确定dp初始化。
- dp[0]表示从第0台阶(那就是地面咯)到楼顶最低花费,所以dp[0]=0
- dp[1]表示从第1台阶到楼顶最低花费,所以dp[1]=cost[0]
- 确定for循环长度、顺序、开始位置。
- 举例推导dp数组。
代码
1 | public static int test(int[] cost) { |
爬楼梯(进阶版)
题目描述
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬至多m (1 <= m < n)个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
输入描述:输入共一行,包含两个正整数,分别表示n, m
输出描述:输出一个整数,表示爬到楼顶的方法数。
1 | 输入示例:3 2 |
解题思路
这里完全背包问题。
动态规划五部曲:
- 确定dp[i]。dp[i]表示踏上第i台阶有dp[i]种方法
- dp[i-j]:踏上第i-j台阶,那么只需要再爬j个台阶即可到达第i台阶,
共dp[i-j]方式
- dp[i-j]:踏上第i-j台阶,那么只需要再爬j个台阶即可到达第i台阶,
- 确定状态转移方程。
1
dp[i] += dp[i-j]
- 确定dp初始化。 p[0]表示踏上第0台阶(那就是地面咯),所以dp[0]=1
- 确定for循环长度、顺序、开始位置。
- 举例推导dp数组。
代码
1 | public static int test(int n, int m) { |