代码随想录算法训练营第38天|● 理论基础 ● 509. 斐波那契数● 70. 爬楼梯 ● 746. 使用最小花费爬楼梯

动态规划理论基础

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

所以动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心,贪心没有状态推导,而是从局部直接选最优的,


动态规划做题步骤

  1. 确定dp数组(dp table)以及下标的含义
  2. 确定递推公式
  3. dp数组如何初始化
  4. 确定遍历顺序
  5. 举例推导dp数组

动态规划做题debug

  1. 找问题的最好方式就是把dp数组打印出来
  2. 做动规的题目,写代码之前一定要把状态转移在dp数组的上具体情况模拟一遍,心中有数,确定最后推出的是想要的结果

斐波那契数

509. 斐波那契数 - 力扣(LeetCode)

本题为动态规划入门题,根据题目进行模拟即可

1.确定dp数组以及下标的含义

dp[i]的定义为:第i个数的斐波那契数值是dp[i]

2.确定递推公式

为什么这是一道非常简单的入门题目呢?

因为题目已经把递推公式直接给我们了:状态转移方程 dp[i] = dp[i - 1] + dp[i - 2];

3.dp数组如何初始化

题目中把如何初始化也直接给我们了,如下:

arr[0]=0;

arr[1]=1;

4.确定遍历顺序

从递归公式dp[i] = dp[i - 1] + dp[i - 2];中可以看出,dp[i]是依赖 dp[i - 1] 和 dp[i - 2],那么遍历的顺序一定是从前到后遍历的

class Solution {
    public int fib(int n) {
     if (n <= 1) {
            return n;
        }
        int[] arr = new int[2];
        arr[0] = 0;
        arr[1] = 1;

        for (int i = 2; i <= n; i++) {
            int sum = arr[0] + arr[1];
            arr[0] = arr[1];
            arr[1] = sum;
        }
        return arr[1];
    }
}

爬楼梯

70. 爬楼梯 - 力扣(LeetCode)

     1.确定dp数组(dp table)以及下标的含义

          到达第i 层有dp[i]种方法

      2.确定递推公式

           dp[i]=dp[i-1]+dp[i-2]

      3.dp数组如何初始化

           dp[1]=1;  

          dp[2]=1;

     4.确定遍历顺序

         从前向后遍历

代码:

class Solution {
    public int climbStairs(int n) {
        if(n<=2){
            return n;
        }
        int[] arr = new int[2];
        arr[0] = 1;
        arr[1] = 2;
        for (int i = 3; i <= n; i++) {
            int sum = arr[0] + arr[1];
            arr[0] = arr[1];
            arr[1] = sum;
        }
        return arr[1];
    }
}

使用最小花费爬楼梯 

746. 使用最小花费爬楼梯 - 力扣(LeetCode)

1.确定dp数组以及下标的含义

    dp[i]的定义:到达第i台阶所花费的最少体力为dp[i]。  

2.确定递推公式

      dp[i - 1] 跳到 dp[i] 需要花费 dp[i - 1] + cost[i - 1]。

     dp[i - 2] 跳到 dp[i] 需要花费 dp[i - 2] + cost[i - 2]。

    那么dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);

3.dp数组初始化

由题目可以知道你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。所以从0或1开始不需要花钱

dp[0]=0;dp[1]=0;

4.遍历顺序

从前向后

class Solution {
    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];
    }
}

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-06-17 22:16:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-17 22:16:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-17 22:16:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-17 22:16:01       20 阅读

热门阅读

  1. R-Tree

    2024-06-17 22:16:01       6 阅读
  2. 安卓开发serizeable和parcelble的区别

    2024-06-17 22:16:01       6 阅读
  3. 深入探索Spring Boot:原理与实践

    2024-06-17 22:16:01       7 阅读
  4. CSS基础

    CSS基础

    2024-06-17 22:16:01      7 阅读
  5. Android WindowFeature小探究

    2024-06-17 22:16:01       6 阅读
  6. css预处理是什么?作用是什么?

    2024-06-17 22:16:01       8 阅读
  7. 一千题,No.0064(螺旋矩阵)

    2024-06-17 22:16:01       8 阅读
  8. MinIO:构建未来的开源对象存储解决方案

    2024-06-17 22:16:01       8 阅读
  9. LeetCode-day11-2813. 子序列最大优雅度

    2024-06-17 22:16:01       7 阅读
  10. Android Root全教程

    2024-06-17 22:16:01       5 阅读
  11. Django 使用Apscheduler执行定时任务

    2024-06-17 22:16:01       8 阅读
  12. git入门

    git入门

    2024-06-17 22:16:01      8 阅读