一、动态规划五部曲
1.确定dp数组以及下标的含义
2.确定递推公式
3.dp数组的初始化
4.确定遍历顺序
5.举例推导dp数组
二、基础动态规划习题
代码部分
class Solution {
public:
int fib(int n) {
//动态规划五部曲
//1.确定dp数组以及dp数组下标的含义
//dp数组含义是存放第i个数的值,下标i的含义是第i个元素
//2.递推公式
//斐波那契推导公式dp[i]=dp[i-1] + dp[i-2]
//3.dp数组的初始化
//dp[0]=0, dp[1]=1
//4.遍历顺序
//推导公式是先直到dp[0]和dp[1]才能直到dp[2]
//5.把dp数组打印出来看和我们推导出来的数列是不是一致的
//先判断是否合法
if(n <= 1){
return n;
}
//因为输入的n比数组的n大1,数组下标从0开始,所以要多申请一个空间
vector<int> dp(n+1);
//dp数组初始化
dp[0] = 0;
dp[1] = 1;
for(int i = 2; i <= n; i++){
//递推公式
dp[i]=dp[i-1] + dp[i-2];
}
return dp[n];
}
};
改进
由于上述是保存一整个dp数组,而我们求dp[i]只需要保存dp[i-1]和dp[i-2]即可
class Solution {
public:
int fib(int n) {
//动态规划五部曲
//1.确定dp数组以及dp数组下标的含义
//dp数组含义是存放第i个数的值,下标i的含义是第i个元素
//2.递推公式
//斐波那契推导公式dp[i]=dp[i-1] + dp[i-2]
//3.dp数组的初始化
//dp[0]=0, dp[1]=1
//4.遍历顺序
//推导公式是先直到dp[0]和dp[1]才能直到dp[2]
//5.把dp数组打印出来看和我们推导出来的数列是不是一致的
//先判断是否合法
if(n <= 1){
return n;
}
int dp[2];
//初始化
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;
}
//最后dp[1]即为我们相求的dp[n]的值
return dp[1];
}
};