Zero title: Algorithm (leetcode, with mind map + all solutions) of 300 questions (2312) sell wood blocks
a topic description
Two solutions overview (mind map)
All three solutions
Interviewer: Seeing that you are almost ready, let's start the interview.
Madman Zhang San: okk~
Interviewer: If the topic is almost the same, let’s talk about your thoughts and ideas~
Madman Zhang San: Because the title contains the word "most" , I think the use of "dynamic programming" should be given priority.
Interviewer: Then what do you think are the conditions for using dynamic programming?
Madman Zhang San: I personally think that two conditions should be met:
**1) Optimal substructure
2) No aftereffect
**
Interviewer: Very good, then do you know the essence of dynamic programming and the steps to solve the problem?
Madman Zhang San:
**1) Essence: a technology that trades space for time
2) Problem solving steps: There are 3 steps. State definition: the decision of each state, storing the variables of each state; state transition equation: the transition relationship between the current state and the previous state; initial state: the initial state or boundary conditions, etc. **
Interviewer: Boy, yes. I think you are almost done with the heat, so you can use the above knowledge to solve this problem~
Narrator: After 5-10 minutes, Zhang San couldn't write the code for a long time.
Interviewer: (with a dignified and confused look) Have you only memorized the relevant concepts and never coded the relevant topics?
Madman Zhang San: (Zhang San loses his timid expression) Uh. . . .
Interviewer: In this way, you can imagine the wooden block as a big watermelon, and it will be cool and refreshing when you write the code~
Then the problem becomes - you have a large watermelon with a two-dimensional (length w, width h) , you can choose to sell it directly (if someone happens to buy a length w and a width h at this time) ), otherwise the big watermelon at this time can only get 0 yuan
Madman Zhang San: Yes, then we can also choose not to sell the big watermelon at this time, cut the melon horizontally and vertically, cut the big watermelon into different small watermelons continuously, and finally calculate the current The maximum price that a large watermelon can be sold for.
Interviewer: Yes, then according to what you said before, write down the state definition and state transition equation~
Madman Zhang San: Okay.
The definition of state as I understand it - dpi, the maximum amount of money that can be obtained when the length is i and the width is j.
State transition equation - when cutting the melon horizontally: dpi = max(dpi, dpk + dpi - k), and the range of k is [1, i - 1].
When cutting melon vertically: dpi = max(dpi, dpi + dpi), the range of k is [1, j - 1].
Interviewer: What about the initialization of the state?
Madman Zhang San: Initialize according to the array prices - when i and j exist at the subscript positions of 0 and 1 in prices, dpi = the subscript of the element corresponding to prices.
Interviewer: Very good, since the idea has been sorted out, then start your performance, ah no, start your code writing~
Next to: Zhang San was like Ren and Du’s second vein being opened up in an instant, and he typed out the code in less than 10 minutes~
1 Scenario 1
1) Code:
// 方案1 “动态规划法 - 普通版”。
// “技巧:题干中含有 最 字眼,优先考虑动态规划(本质:以空间换时间的技术)。”
// 参考:
// 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 = new Array(m + 1).fill(1).map(v => new Array(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] 。
var sellingWood = function(m, n, prices) {
// 1.1)状态初始化:l = prices.length;
// dp = new Array(m + 1).fill(1).map(v => new Array(n + 1).fill(0));
// 思考:二维的每个元素为啥都先 默认填充0 ?
const l = prices.length;
let dp = new Array(m + 1).fill(1).map(v => new Array(n + 1).fill(0));
// 1.2)状态初始化:遍历 数组 prices ,进一步初始化 数组 dp 。
for (let i = 0; i < l; i++) {
const [width, height, price] = prices[i];
dp[width][height] = price;
}
// 2)核心:状态转移。
for (let i = 1; i <= m; i++) {
for (let j = 1; j <= n; j++) {
// 2.1)横向切:dp[i][j] = max(dp[i][j], dp[k][j] + dp[i - k][j]),k的范围为 [1, i - 1]。
for (let k = 1; k < i; k++) {
dp[i][j] = Math.max(dp[i][j], dp[k][j] + dp[i - k][j]);
}
// 2.2)纵向切:dp[i][j] = max(dp[i][j], dp[i][k] + dp[i][j - k]),k的范围为 [1, j - 1]。
for (let k = 1; k < j; k++) {
dp[i][j] = Math.max(dp[i][j], dp[i][k] + dp[i][j - k]);
}
}
}
// 3)返回结果 dp[m][n] 。
return dp[m][n];
};
2 Option 2
Interviewer: Good. The code structure is very hierarchical, and the comments are also placed in a very suitable position~
Madman Zhang San: After all, this "two-dimensional big watermelon" is guaranteed to be ripe. I can guarantee that the algorithm here must be optimal and can guarantee the highest price for our big watermelon.
Interviewer: Are you sure that your "big watermelon cutting algorithm" is ripe? I don't think so?
Madman Zhang San: I am a serious algorithm person, can I still write you the "raw melon algorithm"?
Interviewer: I ask you, is this "big watermelon cutting algorithm" guaranteed to be ripe?
Madman Zhang San: Just tell me if I can pass this interview~
Interviewer:
Madman Zhang San: Then I'll take a look and think about optimization.
Narrator: I saw Zhang San wrote the code running process on the paper.
...
dp5 = max(dp5, dp1 + dp4, dp2 + dp3, dp3 + dp2, dp2 + dp1)
...
Madman Zhang San: It seems that there is indeed an optimization point - there are a lot of redundant calculations, we only need to enumerate the subscript k to half the position - that is, the range of k is [1, i / 2 (downwards) Rounding)] .
1) Code:
// 方案2 “动态规划法 - 优化版”。
// “技巧:题干中含有 最 字眼,优先考虑动态规划(本质:以空间换时间的技术)。”
// 参考:
// 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 = new Array(m + 1).fill(1).map(v => new Array(n + 1).fill(0));
// 思考:二维的每个元素为啥都先 默认填充0 ?
// 1.2)状态初始化:遍历 数组 prices ,进一步初始化 数组 dp 。
// 2)核心:状态转移(有优化,存在对称性,k枚举到i、j的1半的位置即可)。
// 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] 。
var sellingWood = function(m, n, prices) {
// 1.1)状态初始化:l = prices.length;
// dp = new Array(m + 1).fill(1).map(v => new Array(n + 1).fill(0));
// 思考:二维的每个元素为啥都先 默认填充0 ?
const l = prices.length;
let dp = new Array(m + 1).fill(1).map(v => new Array(n + 1).fill(0));
// 1.2)状态初始化:遍历 数组 prices ,进一步初始化 数组 dp 。
for (let i = 0; i < l; i++) {
const [width, height, price] = prices[i];
dp[width][height] = price;
}
// 2)核心:状态转移。
for (let i = 1; i <= m; i++) {
for (let j = 1; j <= n; j++) {
// 2.1)横向切:dp[i][j] = max(dp[i][j], dp[k][j] + dp[i - k][j]),k的范围为 [1, i / 2(向下取整)]。
for (let k = 1; k <= Math.floor(i / 2); k++) {
dp[i][j] = Math.max(dp[i][j], dp[k][j] + dp[i - k][j]);
}
// 2.2)纵向切:dp[i][j] = max(dp[i][j], dp[i][k] + dp[i][j - k]),k的范围为 [1, j / 2(向下取整)]。
for (let k = 1; k <= Math.floor(j / 2); k++) {
dp[i][j] = Math.max(dp[i][j], dp[i][k] + dp[i][j - k]);
}
}
}
// 3)返回结果 dp[m][n] 。
return dp[m][n];
};
Narrator: After Zhang San wrote the above code, he hurriedly asked the interviewer.
Madman Zhang San: Did you pass the interview?
Interviewer:
Madman Zhang San:
Another offer, and I'm going to be the CEO soon. Should I go to eat Shaxian snacks in the evening? Or Lanzhou Ramen ? Alas, having too many choices is also an annoyance!
Four resource sharing & more
1 Historical Articles - Overview
2 Introduction to bloggers
Code Farmer Sanshao, a blogger dedicated to writing minimalist but complete problem solutions (algorithms ).
Focus on one question, multiple solutions, structured thinking , welcome to brush through LeetCode ~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。