##1.动态规划系列
1.思路: 借鉴(代码随想录)
持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情
-
创建dp数组来保存递归的结果
-
确定dp数组以及下标的含义
-
确定递推公式
dp[i] = dp[i - 1] + dp[i - 2];
-
dp数组如何初始化
dp[0] = 0; dp[1] = 1;
-
确定遍历顺序
-
举例推导dp数组
2.常见题型
1.背包问题
2.打家劫舍
3.股票问题
4.子序列问题
3.leetcode-3道题
1.509 斐波那契数
题目不在赘述,耳熟能详
题目已经给出推导的公式,只需要初始化特殊值,f(n)=0,f(n)=1
可以递归用公式推导,此处写dp思路
假设p、q、r(r为结果)整体为滑块,滑块像左推 ,会有以下规律
p q r
0 0 1 i=2
0 1 1 i=3
1 2 3 i=4
2 3 5 i=5
public int fib(int n) {
• if(n<2)
• return n;
• int p=0,q=0,r=1;
• for(int i=2;i<=n;i++){
• p = q;
• q = r;
• r = p + q;
• }
• return r;
• }
2.leetcode-70 爬楼梯
题目描述:每次可以爬1或者2个台阶,求爬到楼顶有多少种方法
思路:
1.n=1 1阶 1种
2.n=2 1阶+1阶 2种
2阶
3.n=3 1阶+1阶+1阶 3种(2+1)
2阶+1阶
1阶+2阶
4.n=4 1阶+1阶+1阶+1阶 5种(3+2)
2阶+1阶+1阶
1阶+2阶+1阶
1阶+1阶+2阶
2阶+2阶
推导出公式,和斐波那契一致,只是在初始化不同
public int climbStairs(int n) {
if(n<3)
return n;
int p=1,q=2,r=0;
for(int i=3;i<=n;i++){
r = p+q;
p =q;
q= r;
}
return r;
}
3.746 使用最小花费爬楼梯
题目描述:给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶
这道题是爬楼梯的变种题,只是给每一个楼梯增加了费用
思路:
1.推导公式,可以见上一个题 只是我们需要分清开始和结束
起点->10->15->20->到达
起点开始,我们走1阶和2阶不用付费,到达了才给钱,所以
dp[0] = cost[0]; dp[1] = cost[1];
就能推出公式为:Math.min(dp[i-1],dp[i-2])+cost[i],我们取1阶和2阶里面最小的加上费用
但是如例子1,10,15,20 按照思路下标为2时,会被修改为10+20=30(10.15.30)并不是最小的,
所以我们用结束倒推,如果到达了终点,找走一步还是两步才是最优解
Math.min(dp[n-1],dp[n-2])
public int minCostClimbingStairs(int[] cost) {
int n = cost.length;
int[] dp = new int[n];
dp[0] = cost[0];
dp[1] = cost[1];
for(int i=2;i<n;i++){
dp[i] = Math.min(dp[i-1],dp[i-2])+cost[i];
}
//已经到达终点,看走一步还是走两步是最优解
return Math.min(dp[n-1],dp[n-2]);
}
\