何为动态规划
动态规划就是Dynamic Programming,简称DP。如果解决一个问题需要解决它的很多重叠子问题,这个时候就需要用到动态规划。
动态规划的解题步骤:
- 确定dp数组以及下标的含义
- 确定递推公式
- dp数组的初始化
- 确定遍历顺序
- 举例推导dp数组
题目背景
今天写的第一题是我们的老熟题:509. 斐波那契数 。这个题目之前用的是递归,今天是动态规划。今天的第二题就有点难理解了:746. 使用最小花费爬楼梯。
代码如下
- 斐波那契数
class Solution {
public int fib(int n) {
if(n<=1)
return n;
int[] dp=new int[n+1];
dp[0]=0;
dp[1]=1;
for(int i=2;i<dp.length;i++){
dp[i]=dp[i-1]+dp[i-2];//这个就是递推公式
}
return dp[n];
}
}
- 使用最小花费爬楼梯
class Solution {
public int minCostClimbingStairs(int[] cost) {
int len=cost.length;
int[] dp=new int[len];
dp[0]=cost[0];
dp[1]=cost[1];
for(int i=2;i<len;i++){
//递推关系式
dp[i]=Math.min(dp[i-1]+cost[i],dp[i-2]+cost[i]);
}
return Math.min(dp[len-1],dp[len-2]);
}
}
分析与小结
从题解代码就可以很清楚的看出,dp数组的下标就表示第几个斐波那契数,而数组相对存储的就是第几个斐波那契数的值,递推公式题目也给了。所以解题十分方便。而第二题是斐波那契数列的变形,非常巧妙。我们每到达一个阶梯,都是从它的上一级或者上两级阶梯,所以当前花费最小将从它的上一级花费和上上一级花费之中诞生。这就是递推关系式: dp[i]=Math.min(dp[i-1]+cost[i],dp[i-2]+cost[i]);的由来。
今天的动态规划就到这里,持之以恒!