This commit is contained in:
krahets
2023-11-09 05:13:54 +08:00
parent 9a09f9407e
commit 3f666fa676
85 changed files with 619 additions and 610 deletions

View File

@@ -3448,14 +3448,14 @@
<p>给定一个 <span class="arithmatex">\(n \times m\)</span> 的二维网格 <code>grid</code> ,网格中的每个单元格包含一个非负整数,表示该单元格的代价。机器人以左上角单元格为起始点,每次只能向下或者向右移动一步,直至到达右下角单元格。请返回从左上角到右下角的最小路径和。</p>
</div>
<p>图 14-10 展示了一个例子,给定网格的最小路径和为 <span class="arithmatex">\(13\)</span></p>
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_example.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="最小路径和示例数据" src="../dp_solution_pipeline.assets/min_path_sum_example.png" /></a></p>
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_example.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="最小路径和示例数据" class="animation-figure" src="../dp_solution_pipeline.assets/min_path_sum_example.png" /></a></p>
<p align="center"> 图 14-10 &nbsp; 最小路径和示例数据 </p>
<p><strong>第一步:思考每轮的决策,定义状态,从而得到 <span class="arithmatex">\(dp\)</span></strong></p>
<p>本题的每一轮的决策就是从当前格子向下或向右一步。设当前格子的行列索引为 <span class="arithmatex">\([i, j]\)</span> ,则向下或向右走一步后,索引变为 <span class="arithmatex">\([i+1, j]\)</span><span class="arithmatex">\([i, j+1]\)</span> 。因此,状态应包含行索引和列索引两个变量,记为 <span class="arithmatex">\([i, j]\)</span></p>
<p>状态 <span class="arithmatex">\([i, j]\)</span> 对应的子问题为:从起始点 <span class="arithmatex">\([0, 0]\)</span> 走到 <span class="arithmatex">\([i, j]\)</span> 的最小路径和,解记为 <span class="arithmatex">\(dp[i, j]\)</span></p>
<p>至此,我们就得到了图 14-11 所示的二维 <span class="arithmatex">\(dp\)</span> 矩阵,其尺寸与输入网格 <span class="arithmatex">\(grid\)</span> 相同。</p>
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_solution_step1.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="状态定义与 dp 表" src="../dp_solution_pipeline.assets/min_path_sum_solution_step1.png" /></a></p>
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_solution_step1.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="状态定义与 dp 表" class="animation-figure" src="../dp_solution_pipeline.assets/min_path_sum_solution_step1.png" /></a></p>
<p align="center"> 图 14-11 &nbsp; 状态定义与 dp 表 </p>
<div class="admonition note">
@@ -3469,7 +3469,7 @@
<div class="arithmatex">\[
dp[i, j] = \min(dp[i-1, j], dp[i, j-1]) + grid[i, j]
\]</div>
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_solution_step2.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="最优子结构与状态转移方程" src="../dp_solution_pipeline.assets/min_path_sum_solution_step2.png" /></a></p>
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_solution_step2.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="最优子结构与状态转移方程" class="animation-figure" src="../dp_solution_pipeline.assets/min_path_sum_solution_step2.png" /></a></p>
<p align="center"> 图 14-12 &nbsp; 最优子结构与状态转移方程 </p>
<div class="admonition note">
@@ -3480,7 +3480,7 @@ dp[i, j] = \min(dp[i-1, j], dp[i, j-1]) + grid[i, j]
<p><strong>第三步:确定边界条件和状态转移顺序</strong></p>
<p>在本题中,首行的状态只能从其左边的状态得来,首列的状态只能从其上边的状态得来,因此首行 <span class="arithmatex">\(i = 0\)</span> 和首列 <span class="arithmatex">\(j = 0\)</span> 是边界条件。</p>
<p>如图 14-13 所示,由于每个格子是由其左方格子和上方格子转移而来,因此我们使用采用循环来遍历矩阵,外循环遍历各行、内循环遍历各列。</p>
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_solution_step3.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="边界条件与状态转移顺序" src="../dp_solution_pipeline.assets/min_path_sum_solution_step3.png" /></a></p>
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_solution_step3.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="边界条件与状态转移顺序" class="animation-figure" src="../dp_solution_pipeline.assets/min_path_sum_solution_step3.png" /></a></p>
<p align="center"> 图 14-13 &nbsp; 边界条件与状态转移顺序 </p>
<div class="admonition note">
@@ -3733,7 +3733,7 @@ dp[i, j] = \min(dp[i-1, j], dp[i, j-1]) + grid[i, j]
</div>
<p>图 14-14 给出了以 <span class="arithmatex">\(dp[2, 1]\)</span> 为根节点的递归树,其中包含一些重叠子问题,其数量会随着网格 <code>grid</code> 的尺寸变大而急剧增多。</p>
<p>本质上看,造成重叠子问题的原因为:<strong>存在多条路径可以从左上角到达某一单元格</strong></p>
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dfs.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="暴力搜索递归树" src="../dp_solution_pipeline.assets/min_path_sum_dfs.png" /></a></p>
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dfs.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="暴力搜索递归树" class="animation-figure" src="../dp_solution_pipeline.assets/min_path_sum_dfs.png" /></a></p>
<p align="center"> 图 14-14 &nbsp; 暴力搜索递归树 </p>
<p>每个状态都有向下和向右两种选择,从左上角走到右下角总共需要 <span class="arithmatex">\(m + n - 2\)</span> 步,所以最差时间复杂度为 <span class="arithmatex">\(O(2^{m + n})\)</span> 。请注意,这种计算方式未考虑临近网格边界的情况,当到达网络边界时只剩下一种选择。因此实际的路径数量会少一些。</p>
@@ -4037,7 +4037,7 @@ dp[i, j] = \min(dp[i-1, j], dp[i, j-1]) + grid[i, j]
</div>
</div>
<p>如图 14-15 所示,在引入记忆化后,所有子问题的解只需计算一次,因此时间复杂度取决于状态总数,即网格尺寸 <span class="arithmatex">\(O(nm)\)</span></p>
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dfs_mem.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="记忆化搜索递归树" src="../dp_solution_pipeline.assets/min_path_sum_dfs_mem.png" /></a></p>
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dfs_mem.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="记忆化搜索递归树" class="animation-figure" src="../dp_solution_pipeline.assets/min_path_sum_dfs_mem.png" /></a></p>
<p align="center"> 图 14-15 &nbsp; 记忆化搜索递归树 </p>
<h3 id="3">3. &nbsp; 方法三:动态规划<a class="headerlink" href="#3" title="Permanent link">&para;</a></h3>
@@ -4356,40 +4356,40 @@ dp[i, j] = \min(dp[i-1, j], dp[i, j-1]) + grid[i, j]
<div class="tabbed-set tabbed-alternate" data-tabs="4:12"><input checked="checked" id="__tabbed_4_1" name="__tabbed_4" type="radio" /><input id="__tabbed_4_2" name="__tabbed_4" type="radio" /><input id="__tabbed_4_3" name="__tabbed_4" type="radio" /><input id="__tabbed_4_4" name="__tabbed_4" type="radio" /><input id="__tabbed_4_5" name="__tabbed_4" type="radio" /><input id="__tabbed_4_6" name="__tabbed_4" type="radio" /><input id="__tabbed_4_7" name="__tabbed_4" type="radio" /><input id="__tabbed_4_8" name="__tabbed_4" type="radio" /><input id="__tabbed_4_9" name="__tabbed_4" type="radio" /><input id="__tabbed_4_10" name="__tabbed_4" type="radio" /><input id="__tabbed_4_11" name="__tabbed_4" type="radio" /><input id="__tabbed_4_12" name="__tabbed_4" type="radio" /><div class="tabbed-labels"><label for="__tabbed_4_1">&lt;1&gt;</label><label for="__tabbed_4_2">&lt;2&gt;</label><label for="__tabbed_4_3">&lt;3&gt;</label><label for="__tabbed_4_4">&lt;4&gt;</label><label for="__tabbed_4_5">&lt;5&gt;</label><label for="__tabbed_4_6">&lt;6&gt;</label><label for="__tabbed_4_7">&lt;7&gt;</label><label for="__tabbed_4_8">&lt;8&gt;</label><label for="__tabbed_4_9">&lt;9&gt;</label><label for="__tabbed_4_10">&lt;10&gt;</label><label for="__tabbed_4_11">&lt;11&gt;</label><label for="__tabbed_4_12">&lt;12&gt;</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dp_step1.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="最小路径和的动态规划过程" src="../dp_solution_pipeline.assets/min_path_sum_dp_step1.png" /></a></p>
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dp_step1.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="最小路径和的动态规划过程" class="animation-figure" src="../dp_solution_pipeline.assets/min_path_sum_dp_step1.png" /></a></p>
</div>
<div class="tabbed-block">
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dp_step2.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="min_path_sum_dp_step2" src="../dp_solution_pipeline.assets/min_path_sum_dp_step2.png" /></a></p>
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dp_step2.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="min_path_sum_dp_step2" class="animation-figure" src="../dp_solution_pipeline.assets/min_path_sum_dp_step2.png" /></a></p>
</div>
<div class="tabbed-block">
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dp_step3.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="min_path_sum_dp_step3" src="../dp_solution_pipeline.assets/min_path_sum_dp_step3.png" /></a></p>
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dp_step3.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="min_path_sum_dp_step3" class="animation-figure" src="../dp_solution_pipeline.assets/min_path_sum_dp_step3.png" /></a></p>
</div>
<div class="tabbed-block">
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dp_step4.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="min_path_sum_dp_step4" src="../dp_solution_pipeline.assets/min_path_sum_dp_step4.png" /></a></p>
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dp_step4.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="min_path_sum_dp_step4" class="animation-figure" src="../dp_solution_pipeline.assets/min_path_sum_dp_step4.png" /></a></p>
</div>
<div class="tabbed-block">
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dp_step5.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="min_path_sum_dp_step5" src="../dp_solution_pipeline.assets/min_path_sum_dp_step5.png" /></a></p>
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dp_step5.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="min_path_sum_dp_step5" class="animation-figure" src="../dp_solution_pipeline.assets/min_path_sum_dp_step5.png" /></a></p>
</div>
<div class="tabbed-block">
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dp_step6.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="min_path_sum_dp_step6" src="../dp_solution_pipeline.assets/min_path_sum_dp_step6.png" /></a></p>
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dp_step6.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="min_path_sum_dp_step6" class="animation-figure" src="../dp_solution_pipeline.assets/min_path_sum_dp_step6.png" /></a></p>
</div>
<div class="tabbed-block">
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dp_step7.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="min_path_sum_dp_step7" src="../dp_solution_pipeline.assets/min_path_sum_dp_step7.png" /></a></p>
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dp_step7.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="min_path_sum_dp_step7" class="animation-figure" src="../dp_solution_pipeline.assets/min_path_sum_dp_step7.png" /></a></p>
</div>
<div class="tabbed-block">
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dp_step8.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="min_path_sum_dp_step8" src="../dp_solution_pipeline.assets/min_path_sum_dp_step8.png" /></a></p>
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dp_step8.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="min_path_sum_dp_step8" class="animation-figure" src="../dp_solution_pipeline.assets/min_path_sum_dp_step8.png" /></a></p>
</div>
<div class="tabbed-block">
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dp_step9.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="min_path_sum_dp_step9" src="../dp_solution_pipeline.assets/min_path_sum_dp_step9.png" /></a></p>
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dp_step9.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="min_path_sum_dp_step9" class="animation-figure" src="../dp_solution_pipeline.assets/min_path_sum_dp_step9.png" /></a></p>
</div>
<div class="tabbed-block">
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dp_step10.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="min_path_sum_dp_step10" src="../dp_solution_pipeline.assets/min_path_sum_dp_step10.png" /></a></p>
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dp_step10.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="min_path_sum_dp_step10" class="animation-figure" src="../dp_solution_pipeline.assets/min_path_sum_dp_step10.png" /></a></p>
</div>
<div class="tabbed-block">
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dp_step11.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="min_path_sum_dp_step11" src="../dp_solution_pipeline.assets/min_path_sum_dp_step11.png" /></a></p>
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dp_step11.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="min_path_sum_dp_step11" class="animation-figure" src="../dp_solution_pipeline.assets/min_path_sum_dp_step11.png" /></a></p>
</div>
<div class="tabbed-block">
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dp_step12.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="min_path_sum_dp_step12" src="../dp_solution_pipeline.assets/min_path_sum_dp_step12.png" /></a></p>
<p><a class="glightbox" href="../dp_solution_pipeline.assets/min_path_sum_dp_step12.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="min_path_sum_dp_step12" class="animation-figure" src="../dp_solution_pipeline.assets/min_path_sum_dp_step12.png" /></a></p>
</div>
</div>
</div>