训练营打卡Day38
动态规划五部曲
- 确定dp数组(dp table)以及下标的含义
- 确定递推公式
- dp数组如何初始化
- 确定遍历顺序
- 举例推导dp数组
思路
- 当 n = 0 时,返回 0,当 n = 1 时,返回 1。然后通过循环来计算斐波那契数列中第 n 个数字。
- 在循环中,使用一个名为 dp 的 vector 来存储斐波那契数列中前两个数字。
- 在每次循环中,计算前两个数字的和并将其存储在 dp[1] 中,然后将 dp[0] 和 dp[1] 向前移动一位。最后返回 dp[1] 即为第 n 个斐波那契数。
代码
class Solution {
public:
int fib(int n) {
if(n == 0) return 0;
if(n == 1) return 1;
vector<int>dp(2, 0);
dp[0] = 0;
dp[1] = 1;
for(int i = 2; i <=n ;i++)
{
int sum = dp[0] + dp[1];
dp[0] = dp[1];
dp[1] = sum;
}
return dp[1];
}
};
思路
- 定义一个数组dp[n+1]来存储爬到第i级台阶的方案数,初始化dp[0] = 1 。
- 在主程序中,使用两个循环i和j来遍历所有情况,其中i表示当前台阶的级数,j表示每次可以爬的台阶级数。
- 在循环中,每次累加dp[i-j]的值到dp[i]中,最后返回dp[n]的值。
代码
class Solution {
public:
int climbStairs(int n) {
vector<int>dp(n+1, 0);
dp[0] = 1;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= 2 && i >= j; j++)
dp[i] += dp[i - j];
return dp[n];
}
};
思路
- 首先定义一个数组dp,其中dp[i]表示爬到第i阶楼梯所需的最小花费。
- 然后通过循环迭代来更新dp数组中的值。- 在每次循环迭代中,更新 dp[i] 为 min(dp[i-1], dp[i-2]) + cost[i],这表示爬到第 i 阶楼梯的最小花费是爬到第 i-1 阶或第 i-2 阶楼梯的最小花费加上第 i 阶楼梯的花费。
- 最后,返回 min(dp[n-1], dp[n-2]),其中 n 是楼梯的总阶数。
代码
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
vector<int>dp(cost.size());
dp[0] = cost[0];
dp[1] = cost[1];
for(int i = 2; i < cost.size(); i++)
{
int dpi = min(dp[0], dp[1]) + cost[i];
dp[0]= dp[1];
dp[1] = dpi;
}
return min(dp[0], dp[1]);
}
};