day32 动态规划-FibonacciNumber+climbingStairs+minCostClimbing

## 9.dynamic program

### 9.1 Introduction

无论大家之前对动态规划学到什么程度,一定要先看 我讲的 动态规划理论基础。 
如果没做过动态规划的题目,看我讲的理论基础,会有感觉 是不是简单题想复杂了? 
其实并没有,我讲的理论基础内容,在动规章节所有题目都有运用,所以很重要!  
如果做过动态规划题目的录友,看我的理论基础 就会感同身受了。
https://programmercarl.com/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 

https://www.bilibili.com/video/BV13Q4y197Wg  

基础:斐波那契 爬楼梯
经典:背包 打家劫舍 股票 子序列

动态规划五部曲:
1.确定dp数组(dp table)以及下标的含义
2.确定递推公式 
3.dp数组如何初始化(0/1确认很有讲究,很重要)
4.确定遍历顺序
5.打印dp数组(动态规划代码简短,直接看打印出来的dp数组是不是和自己设想的一致)

### 9.2 509. Fibonacci Number
The Fibonacci numbers, commonly denoted F(n) form a sequence, called the Fibonacci sequence, such that each number is the sum of the two preceding ones, starting from 0 and 1. That is,
F(0) = 0, F(1) = 1
F(n) = F(n - 1) + F(n - 2), for n > 1.
Given n, calculate F(n).
509. 斐波那契数 
很简单的动规入门题,但简单题使用来掌握方法论的,还是要有动规五部曲来分析。
https://leetcode.cn/problems/fibonacci-number/description/
https://programmercarl.com/0509.%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E6%95%B0.html  
https://www.bilibili.com/video/BV1f5411K7mo  
动态规划五部曲:
1.确定dp数组(dp table)以及下标的含义
dp`[i] : i:第i个斐波那契额数;dp[i]:该斐波那契数的数值

2.确定递推公式 
dp`[i] = dp[i-1] + dp[i-2];

3.dp数组如何初始化(0/1确认很有讲究,很重要)
`dp[0] = 1;
`dp[1] = 1;

4.确定遍历顺序
从前向后遍历

5.打印dp数组

```java
public class fibonacciNumber {  
    //完整版  
    public int fib(int n) {  
        if(n < 2) return n;  
        int[] dp = new int[n+1];  
  
        dp[0] = 0;  
        dp[1] = 1;  
  
        for (int i = 2; i <= n; i++) {  
            dp[i] = dp[i-1] + dp[i-2];  
        }  
  
        return dp[n];  
    }  
    //精简版:因为本质上只在操作三个数,所以不需要数组。  
    public int fibCondensed(int n) {  
        if(n < 2) return n;  
  
        int a = 0;  
        int b = 1;  
        int c = a+b;  
  
        for (int i = 2; i < n; i++) {  
            a = b;  
            b = c;  
            c = a+b;  
        }  
  
        return c;  
    }  
}
```
### 9.3 70. Climbing Stairs
You are climbing a staircase. It takes n steps to reach the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
https://leetcode.cn/problems/climbing-stairs/description/
70. 爬楼梯   
本题大家先自己想一想, 之后会发现,和 斐波那契数 有点关系。
https://programmercarl.com/0070.%E7%88%AC%E6%A5%BC%E6%A2%AF.html  
https://www.bilibili.com/video/BV17h411h7UH  

爬到第一层楼梯有一种方法,爬到二层楼梯有两种方法。
三阶:一阶/二阶迈上来的。
其中迈到一阶有1种方法,迈到二阶有2种方法。所以迈到三阶有3种方法。

四阶:要么三阶迈上来,要么二阶迈上来。
其中有3种办法迈到三阶,两种办法迈到2阶。所以迈到四阶有5种方法。

动态规划五部曲:
1.确定dp数组(dp table)以及下标的含义
`dp[i]: 爬到第i层楼梯,有dp[i]种方法

2.确定递推公式 
`dp[i] = dp[i-1] + dp[i-2];

3.dp数组如何初始化(0/1确认很有讲究,很重要)
*leetcode上说明了n为正整数,n不会为0。
`dp[0] = 0;
`dp[1] = 1;
`dp[2] = 2;

4.确定遍历顺序
从前向后遍历

5.打印dp数组(动态规划代码简短,直接看打印出来的dp数组是不是和自己设想的一致)

```java
public class climbingStairs {  
    public int climbStairs(int n) {  
        if(n <= 2) return n;  
        int[] dp = new int[n+1];  
  
        dp[1] = 1;  
        dp[2] = 2;  
  
        for (int i = 3; i <= n; i++) {  
            dp[i] = dp[i-1] + dp[i-2];  
        }  
  
        return dp[n];  
    }  
}
```
### 9.4 746. Min Cost Climbing Stairs
You are given an integer array cost where cost[i] is the cost of ith step on a staircase. Once you pay the cost, you can either climb one or two steps.
You can either start from the step with index 0, or the step with index 1.
Return the minimum cost to reach the top of the floor.
https://leetcode.cn/problems/min-cost-climbing-stairs/description/
 746. 使用最小花费爬楼梯 
这道题目力扣改了题目描述了,现在的题目描述清晰很多,相当于明确说 第一步是不用花费的。 
更改题目描述之后,相当于是 文章中 「拓展」的解法 
https://programmercarl.com/0746.%E4%BD%BF%E7%94%A8%E6%9C%80%E5%B0%8F%E8%8A%B1%E8%B4%B9%E7%88%AC%E6%A5%BC%E6%A2%AF.html   
https://www.bilibili.com/video/BV16G411c7yZ 
动态规划五部曲:
1.确定dp数组(dp table)以及下标的含义
`dp[i]: 爬到第i层楼梯,最少花费精力是dp[i]

2.确定递推公式 
`dp[i] :由dp[i-1] 跳一次/由dp[i-2] 跳两次
跳到 i-1 层需要花费精力`cost[i-1]; 
跳到 i-2 层需要花费精力`cost[i-2]; 

`dp[i] = Math.min(( dp[i-1]+cost[i-1] ),( dp[i-2]+cost[i-2] ));

3.dp数组如何初始化(0/1确认很有讲究,很重要)
*leetcode上说明了 You can either start from the step with index 0, or the step with index 1.
到达0/1的时候,体力消耗是0。
`dp[0] = 0;
`dp[1] = 0;

4.确定遍历顺序
从前向后遍历

5.打印dp数组(动态规划代码简短,直接看打印出来的dp数组是不是和自己设想的一致)
```java
public class minCostClimbingStairs {  
    public minCostClimbingStairs() {    }  
  
    public int minCostClimbingStairs(int[] cost) {  
        int[] dp = new int[cost.length + 1];  
  
        dp[0] = 0;  
        dp[1] = 0;  
  
        for (int i = 2; i <= cost.length; i++) {  
            dp[i] = Math.min((dp[i-1]+cost[i-1]),(dp[i-2]+cost[i-2]));  
        }  
        return dp[cost.length] ;  
    }  
}  
class minCostClimbingStairsTest {  
    public static void main(String[] args) {  
        int[] cost = {1,100,1,1,1,100,1,1,100,1};  
  
        minCostClimbingStairs example = new minCostClimbingStairs();  
        System.out.println(example.minCostClimbingStairs(cost));  
    }  
}
```

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值