前言
终于开始动态规划!!!好好学。
1 理论基础
1.1 动态规划常规题型
- 动态规划基础
- 背包问题
- 打家劫舍
- 股票问题
- 子序列问题
1.2 动态规划解题步骤
- dp数组及下标的含义
- 递推公式
- dp数组如何初始化
- dp数组遍历顺序
- 打印dp数组
509.斐波那契数列
思路
dp写法
class Solution {
public int fib(int n) {
// 定义dp数组
int [] dp = new int[n + 1];
// 递推公式
// f(n) = f(n - 1) + f(n - 2)
// dp数组初始化
if(n < 2) return n;
dp[0] = 0;
dp[1] = 1;
// 遍历顺序
for(int i = 2;i <=n;i ++){
dp[i] = dp[i - 1]+dp[i - 2];
}
// System.out.println(Arrays.toString(dp));
return dp[n];
}
}
递归写法
class Solution {
public int fib(int n) {
if( n < 2) return n;
return fib(n-1) + fib(n - 2);
}
}
爬楼梯
class Solution {
public int climbStairs(int n) {
/* 定义dp数组
dp[i] 表示的多少种方法
i表示在第几节台阶
递推公式:
f(n) = f(n-1) + f(n-2)
*/
int[] dp = new int[n + 1];
if(n <= 2) return n;
dp[0] = 0;
dp[1] = 1;
dp[2] = 2;
for(int i =3;i <= n;i++){
dp[i] = dp[i-1] + dp[i-2] ;
}
return dp[n];
}
}
拓展
如果是到m阶,该如何处理?
完全背包
class Solution {
public int climbStairs(int n) {
int[] dp = new int[n + 1];
if(n <= 2) return n;
dp[1] = 1;
dp[2] = 2;
int m = 2;
for(int i = 3;i <= n;i ++){
for(int j = 1;j <=m;j++){
if(i - j > 0){
dp[i] += dp[i-j];
}
}
}
return dp[n];
}
}
746. 使用最小花费爬楼梯
class Solution {
public int climbStairs(int n) {
int[] dp = new int[n + 1];
if(n <= 2) return n;
dp[1] = 1;
dp[2] = 2;
int m = 2;
for(int i = 3;i <= n;i ++){
for(int j = 1;j <=m;j++){
if(i - j > 0){
dp[i] += dp[i-j];
}
}
}
return dp[n];
}
}