509. 斐波那契数
思路:
动规五部曲:
这里我们要用一个一维dp数组来保存递归的结果
- 确定dp数组以及下标的含义
dp[i]的定义为:第i个数的斐波那契数值是dp[i]
2.确定递推公式
为什么这是一道非常简单的入门题目呢?
因为题目已经把递推公式直接给我们了:状态转移方程 dp[i] = dp[i - 1] + dp[i - 2];
3.dp数组如何初始化
题目中把如何初始化也直接给我们了,如下:
dp[0] = 0;
dp[1] = 1;
4.确定遍历顺序
从递归公式dp[i] = dp[i - 1] + dp[i - 2];中可以看出,dp[i]是依赖 dp[i - 1] 和 dp[i - 2],那么遍历的顺序一定是从前到后遍历的
5.举例推导dp数组
按照这个递推公式dp[i] = dp[i - 1] + dp[i - 2],我们来推导一下,当N为10的时候,dp数组应该是如下的数列:
0 1 1 2 3 5 8 13 21 34 55
代码:
class Solution {
public:
int fib(int n) {
//1/确定dp数组以及下标的含义:第i个数的斐波那契数值是dp[i]
if(n<=1)
{
return n;
}
//2.确定递推公式:dp[i] = dp[i - 1] + dp[i - 2];
int dp[2];
//dp数组的初始化
dp[0] = 0;
dp[1] = 1;
for(int i =2 ;i<=n;i++)//4.确定遍历顺序为前序
{
int sum = dp[0]+dp[1];
dp[0] = dp[1];
dp[1] = sum;
}
return dp[1];
}
};
遇到的问题:
1.对于只需要维护两个dp数组两个参数的思路:因为递推公式只需要两个参数推导,并且结果只需要返回dp数组的最后一个参数
70. 爬楼梯
思路:
五部曲
1.确定dp数组及其下标意义:dp数组表示有多少种方式爬到当前阶层,下标表示阶层数
2.确定递推公式:dp[ i ] = dp[i-1] + dp[i-2] 原因是当前阶层只能由下一层迈一步,或下两层迈两步到达
3.dp数组如何初始化:只需要初始化dp[1]和dp[2]
4.确定遍历顺序:前序
5.列举dp数组:1,2,3,5,8
代码:
class Solution {
public:
int climbStairs(int n) {
int dp[3];
//dp数组的初始化
dp[1] = 1;
dp[2] = 2;
if(n<=2)return dp[n];
for(int i = 3;i<=n;i++)
{
int sum = dp[1]+dp[2];
dp[1] = dp[2];
dp[2] = sum;
}
return dp[2];
}
};
遇到的问题:
1.对于递推公式的如何推导的
使用最小花费爬楼梯
思路:
1.确定dp数组以及下标的含义:dp数组代表到达当前阶层位置要花费的钱数(起点是0或1),下标是阶数
2.确定递推公式:dp[i] = min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]);
3.dp数组如何初始化:初始化到达第一阶和第二阶的花费为0,因为起点为0或1
4.确定遍历顺序:前序
5.例举dp数组
代码:
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
vector<int> dp(cost.size()+1);
dp[0] = 0;
dp[1] = 0;
for(int i = 2 ;i<=cost.size();i++)
{
dp[i] = min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]);
}
return dp[cost.size()];
}
};
遇到的问题:
1.对于cost数组的理解