Day41~509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯

19 阅读3分钟

摘要

本文主要介绍了动态规划的理论基础,以及LeetCode动态规划的几个题目,包括509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯。

1、动态规划理论基础

1.1 概念

什么是动态规划

动态规划,英文:Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。

所以动态规划中每一个状态一定是由上一个状态推导出来的。

动态规划的解题步骤

  • dp 数组以及下标的含义
  • 递推公式
  • dp 数组如何初始化
  • dp 数组遍历顺序
  • 打印 dp 数组

动规规划的常见类型

  • 动规基础
  • 背包问题
  • 打家劫舍
  • 股票问题
  • 子序列问题

2、509.斐波那契数

2.1 思路

  • dp 数组以及下标的含义:第i个数的斐波那契数值是dp[i]
  • 递推公式:dp[i] = dp[i-1] + dp[i-2];
  • dp 数组如何初始化:dp[0] = 0; dp[1] = 1;
  • dp 数组遍历顺序:dp[i]是依赖 dp[i - 1] 和 dp[i - 2],所以是从前往后遍历
  • 打印 dp 数组

2.2 代码

    public int fib(int n) {
        if(n == 0 || n == 1) {
            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];
    }

3、70. 爬楼梯

3.1 思路

  • dp 数组以及下标的含义:爬到第i个台阶有dp[i]种不同的方法可以爬到楼顶

  • 递推公式

    • 上i-1层楼梯,有dp[i - 1]种方法,上i-2层楼梯,有dp[i - 2]种方法
    • 所以dp[i] = dp[i-1] + dp[i-2];
  • dp 数组如何初始化:dp[0] = 0; dp[1] = 1; dp[2] = 2;

  • dp 数组遍历顺序:dp[i]是依赖 dp[i - 1] 和 dp[i - 2],所以是从前往后遍历

  • 打印 dp 数组

3.2 代码

    public int climbStairs(int n) {
        if(n <= 2) {
            return n;
        }
​
        int[] dp = new int[n+1];
        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];
    }

4、746. 使用最小花费爬楼梯

4.1 思路

  • dp 数组以及下标的含义:爬到第i个台阶的最低花费为dp[i]

  • 递推公式

    • 上i-1层楼梯,最低花费为dp[i-1],上i-2层楼梯,最低花费为dp[i-2]
    • 所以dp[i] = Math.min(dp[i-1]+cost[i-1], dp[i-2]+cost[i-2]);
  • dp 数组如何初始化

    • 从下标为 0 或下标为 1 的台阶开始,因此支付费用为0;
    • dp[0] = 0; dp[1] = 0;
  • dp 数组遍历顺序:dp[i]是依赖 dp[i-1] 和 dp[i-2],所以是从前往后遍历

  • 打印 dp 数组

4.2 代码

    public int minCostClimbingStairs(int[] cost) {
        int len = cost.length;
        if(len < 2) {
            return 0;
        }
​
        int[] dp = new int[len+1];
        dp[0] = 0; 
        dp[1] = 0;
​
        for(int i=2; i<=len; i++) {
            dp[i] = Math.min(dp[i-1]+cost[i-1], dp[i-2]+cost[i-2]);
        }
        return dp[len];
    }

参考资料

代码随想录-509.斐波那契数

代码随想录-70. 爬楼梯

代码随想录-746. 使用最小花费爬楼梯