当前位置: 首页 > Web前端 > JavaScript

2312.出售木块-面试官和疯子张三的那些事儿(leetcode,有思维导图+全解)

时间:2023-03-26 20:22:16 JavaScript

零题目:算法(leetcode,有思维导图+全解)300题(2312)卖木头一.说明thetopic2.解决方案概述(思维导图)3.所有解决方案面试官:看你差不多准备好了,下面开始面试。疯张三:okk~面试官:如果你看过题目,我来说说你的想法和想法吧~疯张三:因为题目有“最”字,所以我觉得应该优先考虑。动态规划”。面试官:那你觉得使用动态规划的条件是什么?疯子张三:我个人认为应该满足两个条件:**1)最优子结构2)无后效**面试官:很好,那么你就知道动态规划的本质和解题步骤分别是什么了疯狂的张三:**1)本质:一种用空间换取时间的技术2)解题步骤:分为3个步骤状态定义:每个状态的决策,存储每个状态的变量;状态转移方程:当前状态与前一个状态的转移关系;初始状态:初始状态或边界条件等**面试官:年轻人,是的,我觉得你已经快热身了,所以你可以用上面的知识来解决这个问题~旁白:5-10分钟后,张三写不出代码。面试官:(严肃而困惑)你只是记忆相关概念而不是代码相关主题?张三疯子:(张三一脸胆怯)额。...面试官:这样一来,如果把木块想象成一个大西瓜,写代码的时候就凉爽爽快~那么题目就变成了——你有一个二维(长为w,宽为h)可以选择直接卖掉大西瓜(如果有人此时买,长w,宽h),否则此时的大西瓜只能得到0元。张三疯子:对,然后我们也可以选择这个时候大西瓜不卖,把瓜横着竖着切,把大西瓜切成不同的小西瓜,最后算出当前大西瓜卖的最高价可以从这些切瓜图上卖掉。面试官:对,那按照你之前说的,把状态定义和状态转移方程写下来~张三疯子:好的。我理解的状态定义——dpi,当长度为i,宽度为j时,可以得到的最大金额。状态转移方程——横切瓜时:dpi=max(dpi,dpk+dpi-k),k的取值范围是[1,i-1]。垂直切瓜时:dpi=max(dpi,dpi+dpi),k的取值范围为[1,j-1]。面试官:状态的初始化呢?疯子张三:根据数组prices进行初始化——当i,j存在于prices中0和1的下标位置时,dpi=prices对应的元素下标。面试官:很好,思路理清了,那就开始表演吧,啊不,开始写代码了~旁白:张三就像任督的第二通道瞬间被打开,三次,五次二分,无10分钟敲出代码~1Scheme11)代码://Scheme1《动态编程方法-普通版》。//"技巧:题干中包含最重要的词,动态规划优先(本质:空间换时间的技术)。"//参考://1)https://leetcode.cn/problems/selling-pieces-of-wood/solution/mai-mu-tou-kuai-by-leetcode-solution-gflg///2)https://leetcode.cn/problems/selling-pieces-of-wood/solution/by-endlesscheng-mrmd///思路(把这里的木块想象成一个大西瓜,写代码会爽快爽快~)://1)状态定义:dp[i][j],长度为i,宽度为j时最大可获得的金额。//2)状态转换://2.1)水平切割:dp[i][j]=max(dp[i][j],dp[k][j]+dp[i-k][j]),k的取值范围为[1,i-1]。//2.2)垂直切割:dp[i][j]=max(dp[i][j],dp[i][k]+dp[i][j-k]),k的范围是[1,j-1]。//思路://1.1)状态初始化:l=prices.length;//dp=newArray(m+1).fill(1).map(v=>newArray(n+1).fill(0));//思考:为什么二维的每个元素都用0填充默认情况下?//1.2)状态初始化:遍历数组prices并进一步初始化数组dp。//2)核心:状态转移。//2.1)水平切割:dp[i][j]=max(dp[i][j],dp[k][j]+dp[i-k][j]),k的取值范围是[1,i-1]。//2.2)垂直切割:dp[i][j]=max(dp[i][j],dp[i][k]+dp[i][j-k]),k的范围是[1,j-1]。//3)返回结果dp[m][n]。varsellingWood=function(m,n,prices){//1.1)状态初始化:l=prices.length;//dp=newArray(m+1).fill(1).map(v=>newArray(n+1).fill(0));//思考:为什么二维中的每个元素默认都用0填充?constl=prices.length;让dp=newArray(m+1).fill(1).map(v=>newArray(n+1).fill(0));//1.2)状态初始化:遍历数组prices进一步初始化数组dp。for(leti=0;inewArray(n+1).fill(0));//思考:为什么二维的每个元素都用0填充默认情况下?//1.2)状态初始化:遍历数组prices并进一步初始化数组dp。//2)核心:状态转换(有优化,有对称性,k可以枚举为i和j的一半)。//2.1)水平切割:dp[i][j]=max(dp[i][j],dp[k][j]+dp[i-k][j]),k的取值范围是[1,i/2(向下舍入)]。//2.2)垂直切割:dp[i][j]=max(dp[i][j],dp[i][k]+dp[i][j-k]),k的范围是[1,j/2(向下舍入)]。//3)返回结果dp[m][n]。varsellingWood=function(m,n,prices){//1.1)状态初始化:l=prices.length;//dp=newArray(m+1).fill(1).map(v=>newArray(n+1).fill(0));//思考:为什么二维中的每个元素默认都用0填充?constl=prices.length;让dp=newArray(m+1).fill(1).map(v=>newArray(n+1).fill(0));//1.2)状态初始化:遍历数组prices进一步初始化数组dp。for(leti=0;i