当前位置: 首页 > news >正文

【算法训练营Day25】动态规划part1

文章目录

  • 理论基础
  • 斐波那契数
  • 爬楼梯
  • 使用最小花费爬楼梯
  • 不同路径
  • 不同路径 II

理论基础

动态规划,简称DP,使用场景:某一问题有很多重叠子问题

贪心的思想是局部最优推导出全局最优,而dp的重点在于每一个状态一定是由上一个状态推导而来,正因为状态是连续相关的所以我们一般要借助于dp数组以及递推式来解决问题。

DP中比较常见的几类问题:

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

解题思路:首先想办法把问题化成很多子问题,成功把问题拆分之后,再结合dp数组确定递推公式,根据递推公式确定初始化逻辑以及遍历顺序。

DP问题的解题四部曲:

  • 确定dp数组以及下标的含义【重中之重!!!要以结果为导向去分析dp数组的含义】
  • 确定递推公式
  • dp数组如何初始化
  • 确定遍历顺序

dp问题排查:

把dp数组打印出来,看看究竟是不是按照自己思路推导的!

斐波那契数

题目链接:509. 斐波那契数

用递归做的话,代码如下:

class Solution {public int fib(int n) {if(n == 0) return 0;else if(n == 1) return 1;return fib(n - 1) + fib(n - 2);}
}

如果用动态规划的话,使用dp四部曲:

  • 确认数组及下标含义:数组的每个位置对应斐波那契元素的位置
  • 确定递推公式:dp[i] = dp[i - 1] + dp[i - 2]
  • 确定数组初始化:dp[0] = 0,dp[1] = 1
  • 确定数组遍历顺序:从前往后遍历

代码如下:

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

爬楼梯

题目链接:70. 爬楼梯

解题思路:每次只能爬1或2个阶梯,那么

  • 爬1阶,有1种办法
  • 爬2阶,有2种办法
  • 爬3阶,有两种情况在爬2阶的基础上再爬一阶,以及在爬1阶的基础上爬2阶,一共3种

那么本题和上一题基本一样,区别在于数组的含义与初始化方式。

代码如下:

class Solution {public int climbStairs(int n) {if(n == 1) return 1;else if(n == 2) return 2;int[] dp = new int[n];dp[0] = 1;dp[1] = 2;for(int i  = 2;i < dp.length;i++) {dp[i] = dp[i - 1] + dp[i - 2];}return dp[n - 1];}
}

使用最小花费爬楼梯

题目链接:746. 使用最小花费爬楼梯

解题思路:
和上一题类似,只不过本题加入了一个消费的逻辑。

dp四部曲:

  • 确认数组及下标含义:i表示下标为i的阶梯,dp[i]表示到达下标为i的阶梯要花费的体力
  • 确定递推公式:dp[i] = min{dp[i - 1] + cost[i - 1],dp[i - 2] + cost[i - 2]}
  • 确定数组初始化:dp[0] = 0,dp[1] = 0
  • 确定数组遍历顺序:从前往后遍历

代码如下:

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

不同路径

题目链接:62. 不同路径

解题思路:

本题的关键在于只能向下和向右运动。本题要求起点到终点的路径,我们可以先把问题切小,先找出到到起点右边或者下边有多少条路经,然后一步步递推得到答案。

dp四部曲:

  • dp数组以及下标的含义:dp[i][j]表示从起点到(i,j)的路径有多少条
  • 递推公式:dp[i][j] = dp[i][j - 1] + dp[i + 1][j]
  • 初始化方式:因为dp[i][j]与上面和左边的元素有关,那么初始化的时候先初始化最上面与最左边。又因为只能向下与向右移动,所以第一行与第一列都可以初始化为1
  • 遍历顺序:从左向右,从上往下

解题代码:

class Solution {public int uniquePaths(int m, int n) {int[][] dp = new int[m][n];for(int i = 0;i < m;i++) dp[i][0] = 1;for(int i = 0;i < n;i++) dp[0][i] = 1;for(int i = 1;i < m;i++) for(int j = 1;j < n;j++) dp[i][j] = dp[i][j - 1] + dp[i - 1][j];return dp[m - 1][n - 1];}
}

不同路径 II

题目链接:63. 不同路径 II

解题思路:

和上一题的区别在于有的格子不能走。那么我们在初始化的时候就要注意只要出现了障碍,那么后面都是不可达的!同时在更新dp数组的时候,如果对应的(i,j)处是障碍,那么不可达,路线则是默认的0;

class Solution {public int uniquePathsWithObstacles(int[][] obstacleGrid) {int m = obstacleGrid.length;int n = obstacleGrid[0].length;int[][] dp = new int[m][n];for(int i = 0;i < m;i++) {if(obstacleGrid[i][0] == 1) break;dp[i][0] = 1;} for(int i = 0;i < n;i++) {if(obstacleGrid[0][i] == 1) break;dp[0][i] = 1;}for(int i = 1;i < m;i++) for(int j = 1;j < n;j++) if (obstacleGrid[i][j] == 0) dp[i][j] = dp[i][j - 1] + dp[i - 1][j];return dp[m - 1][n - 1];}
}
http://www.dtcms.com/a/395121.html

相关文章:

  • 打破网络壁垒:使用内网穿透轻松实现远程桌面访问
  • 2025 PyCharm IDE 社区版与专业版合并后,新手该如何安装?(附 Toolbox 图形化安装教程)
  • 07-css元素定位布局
  • 波动率曲面及SVI模型的Python数值拟合
  • 基于Python新闻平台的文本数据挖掘系统
  • 2017/12 JLPT听力原文 问题四
  • 【Tawk】Tawk.to聊天小部件移动端位置调整完整指南
  • jieba 库
  • 开启 3D 之旅 - 你的第一个 WebGL 三角形
  • 基于AWS Lambda的机器学习动态定价系统 CI/CD管道部署方案介绍
  • 3D 文件格式解释
  • 对Hive表进行归档,减少小文件的影响
  • R 中,geo 数据集 分析探针转基因的时候,一个探针对应的多个基因的情况
  • 机器学习-逻辑回归-考试预测通过-1
  • 计算机中用8位如何计算最大值和最小值-128~127
  • PyTorch 神经网络工具箱完全指南
  • docker一键安装部署若依Ruoyi-Vue(保姆级)
  • 通义DeepResearch论文六连发全面解读
  • 大模型应用-prompt提示词工程
  • Windows 命令行:使用路径名和文件名来启动文件
  • 稻瘟病监测仪的功能用途
  • 仿照豆包实现 Prompt 变量模板输入框
  • 如何安装 SQLPro Studio for Mac?v2024.21.dmg 文件安装步骤详解(附安装包)
  • 扣子空间:字节跳动推出的AI Agent 智能体平台
  • 编程基础:表驱动
  • 内网穿透的应用-RemoteJVMDebug+cpolar:内网服务器调试的无界解决方案
  • 如何将PPT每一页批量导出为高清JPG图片?一文讲清操作流程
  • 高防服务器如何实现安全防护?ddos攻击会暴露ip吗?
  • linux硬盘分区管理
  • spring boot实现MCP服务器,及其cursor测试使用的方法