This commit is contained in:
krahets
2023-08-22 13:50:24 +08:00
parent 77b90cd19b
commit b70b7c9e75
67 changed files with 580 additions and 580 deletions

View File

@@ -3603,7 +3603,7 @@
<p>给定 <span class="arithmatex">\(n\)</span> 个物品,第 <span class="arithmatex">\(i\)</span> 个物品的重量为 <span class="arithmatex">\(wgt[i-1]\)</span> 、价值为 <span class="arithmatex">\(val[i-1]\)</span> ,和一个容量为 <span class="arithmatex">\(cap\)</span> 的背包。<strong>每个物品可以重复选取</strong>,问在不超过背包容量下能放入物品的最大价值。</p>
</div>
<p><img alt="完全背包问题的示例数据" src="../unbounded_knapsack_problem.assets/unbounded_knapsack_example.png" /></p>
<p align="center">完全背包问题的示例数据 </p>
<p align="center"> 14-22 &nbsp; 完全背包问题的示例数据 </p>
<h3 id="1">1. &nbsp; 动态规划思路<a class="headerlink" href="#1" title="Permanent link">&para;</a></h3>
<p>完全背包和 0-1 背包问题非常相似,<strong>区别仅在于不限制物品的选择次数</strong></p>
@@ -3837,7 +3837,7 @@ dp[i, c] = \max(dp[i-1, c], dp[i, c - wgt[i-1]] + val[i-1])
</div>
<h3 id="3">3. &nbsp; 状态压缩<a class="headerlink" href="#3" title="Permanent link">&para;</a></h3>
<p>由于当前状态是从左边和上边的状态转移而来,<strong>因此状态压缩后应该对 <span class="arithmatex">\(dp\)</span> 表中的每一行采取正序遍历</strong></p>
<p>这个遍历顺序与 0-1 背包正好相反。请借助图来理解两者的区别。</p>
<p>这个遍历顺序与 0-1 背包正好相反。请借助图 14-23 来理解两者的区别。</p>
<div class="tabbed-set tabbed-alternate" data-tabs="2:6"><input checked="checked" id="__tabbed_2_1" name="__tabbed_2" type="radio" /><input id="__tabbed_2_2" name="__tabbed_2" type="radio" /><input id="__tabbed_2_3" name="__tabbed_2" type="radio" /><input id="__tabbed_2_4" name="__tabbed_2" type="radio" /><input id="__tabbed_2_5" name="__tabbed_2" type="radio" /><input id="__tabbed_2_6" name="__tabbed_2" type="radio" /><div class="tabbed-labels"><label for="__tabbed_2_1">&lt;1&gt;</label><label for="__tabbed_2_2">&lt;2&gt;</label><label for="__tabbed_2_3">&lt;3&gt;</label><label for="__tabbed_2_4">&lt;4&gt;</label><label for="__tabbed_2_5">&lt;5&gt;</label><label for="__tabbed_2_6">&lt;6&gt;</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
@@ -3860,7 +3860,7 @@ dp[i, c] = \max(dp[i-1, c], dp[i, c - wgt[i-1]] + val[i-1])
</div>
</div>
</div>
<p align="center">完全背包的状态压缩后的动态规划过程 </p>
<p align="center"> 14-23 &nbsp; 完全背包的状态压缩后的动态规划过程 </p>
<p>代码实现比较简单,仅需将数组 <code>dp</code> 的第一维删除。</p>
<div class="tabbed-set tabbed-alternate" data-tabs="3:12"><input checked="checked" id="__tabbed_3_1" name="__tabbed_3" type="radio" /><input id="__tabbed_3_2" name="__tabbed_3" type="radio" /><input id="__tabbed_3_3" name="__tabbed_3" type="radio" /><input id="__tabbed_3_4" name="__tabbed_3" type="radio" /><input id="__tabbed_3_5" name="__tabbed_3" type="radio" /><input id="__tabbed_3_6" name="__tabbed_3" type="radio" /><input id="__tabbed_3_7" name="__tabbed_3" type="radio" /><input id="__tabbed_3_8" name="__tabbed_3" type="radio" /><input id="__tabbed_3_9" name="__tabbed_3" type="radio" /><input id="__tabbed_3_10" name="__tabbed_3" type="radio" /><input id="__tabbed_3_11" name="__tabbed_3" type="radio" /><input id="__tabbed_3_12" name="__tabbed_3" type="radio" /><div class="tabbed-labels"><label for="__tabbed_3_1">Java</label><label for="__tabbed_3_2">C++</label><label for="__tabbed_3_3">Python</label><label for="__tabbed_3_4">Go</label><label for="__tabbed_3_5">JS</label><label for="__tabbed_3_6">TS</label><label for="__tabbed_3_7">C</label><label for="__tabbed_3_8">C#</label><label for="__tabbed_3_9">Swift</label><label for="__tabbed_3_10">Zig</label><label for="__tabbed_3_11">Dart</label><label for="__tabbed_3_12">Rust</label></div>
@@ -4081,7 +4081,7 @@ dp[i, c] = \max(dp[i-1, c], dp[i, c - wgt[i-1]] + val[i-1])
<p>给定 <span class="arithmatex">\(n\)</span> 种硬币,第 <span class="arithmatex">\(i\)</span> 种硬币的面值为 <span class="arithmatex">\(coins[i - 1]\)</span> ,目标金额为 <span class="arithmatex">\(amt\)</span> <strong>每种硬币可以重复选取</strong>,问能够凑出目标金额的最少硬币个数。如果无法凑出目标金额则返回 <span class="arithmatex">\(-1\)</span></p>
</div>
<p><img alt="零钱兑换问题的示例数据" src="../unbounded_knapsack_problem.assets/coin_change_example.png" /></p>
<p align="center">零钱兑换问题的示例数据 </p>
<p align="center"> 14-24 &nbsp; 零钱兑换问题的示例数据 </p>
<h3 id="1_1">1. &nbsp; 动态规划思路<a class="headerlink" href="#1_1" title="Permanent link">&para;</a></h3>
<p><strong>零钱兑换可以看作是完全背包的一种特殊情况</strong>,两者具有以下联系与不同点:</p>
@@ -4373,7 +4373,7 @@ dp[i, a] = \min(dp[i-1, a], dp[i, a - coins[i-1]] + 1)
</div>
</div>
</div>
<p>图展示了零钱兑换的动态规划过程,和完全背包非常相似。</p>
<p> 14-25 展示了零钱兑换的动态规划过程,和完全背包非常相似。</p>
<div class="tabbed-set tabbed-alternate" data-tabs="5:15"><input checked="checked" id="__tabbed_5_1" name="__tabbed_5" type="radio" /><input id="__tabbed_5_2" name="__tabbed_5" type="radio" /><input id="__tabbed_5_3" name="__tabbed_5" type="radio" /><input id="__tabbed_5_4" name="__tabbed_5" type="radio" /><input id="__tabbed_5_5" name="__tabbed_5" type="radio" /><input id="__tabbed_5_6" name="__tabbed_5" type="radio" /><input id="__tabbed_5_7" name="__tabbed_5" type="radio" /><input id="__tabbed_5_8" name="__tabbed_5" type="radio" /><input id="__tabbed_5_9" name="__tabbed_5" type="radio" /><input id="__tabbed_5_10" name="__tabbed_5" type="radio" /><input id="__tabbed_5_11" name="__tabbed_5" type="radio" /><input id="__tabbed_5_12" name="__tabbed_5" type="radio" /><input id="__tabbed_5_13" name="__tabbed_5" type="radio" /><input id="__tabbed_5_14" name="__tabbed_5" type="radio" /><input id="__tabbed_5_15" name="__tabbed_5" type="radio" /><div class="tabbed-labels"><label for="__tabbed_5_1">&lt;1&gt;</label><label for="__tabbed_5_2">&lt;2&gt;</label><label for="__tabbed_5_3">&lt;3&gt;</label><label for="__tabbed_5_4">&lt;4&gt;</label><label for="__tabbed_5_5">&lt;5&gt;</label><label for="__tabbed_5_6">&lt;6&gt;</label><label for="__tabbed_5_7">&lt;7&gt;</label><label for="__tabbed_5_8">&lt;8&gt;</label><label for="__tabbed_5_9">&lt;9&gt;</label><label for="__tabbed_5_10">&lt;10&gt;</label><label for="__tabbed_5_11">&lt;11&gt;</label><label for="__tabbed_5_12">&lt;12&gt;</label><label for="__tabbed_5_13">&lt;13&gt;</label><label for="__tabbed_5_14">&lt;14&gt;</label><label for="__tabbed_5_15">&lt;15&gt;</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
@@ -4423,7 +4423,7 @@ dp[i, a] = \min(dp[i-1, a], dp[i, a - coins[i-1]] + 1)
</div>
</div>
</div>
<p align="center">零钱兑换问题的动态规划过程 </p>
<p align="center"> 14-25 &nbsp; 零钱兑换问题的动态规划过程 </p>
<h3 id="3_1">3. &nbsp; 状态压缩<a class="headerlink" href="#3_1" title="Permanent link">&para;</a></h3>
<p>零钱兑换的状态压缩的处理方式和完全背包一致。</p>
@@ -4676,7 +4676,7 @@ dp[i, a] = \min(dp[i-1, a], dp[i, a - coins[i-1]] + 1)
<p>给定 <span class="arithmatex">\(n\)</span> 种硬币,第 <span class="arithmatex">\(i\)</span> 种硬币的面值为 <span class="arithmatex">\(coins[i - 1]\)</span> ,目标金额为 <span class="arithmatex">\(amt\)</span> ,每种硬币可以重复选取,<strong>问在凑出目标金额的硬币组合数量</strong></p>
</div>
<p><img alt="零钱兑换问题 II 的示例数据" src="../unbounded_knapsack_problem.assets/coin_change_ii_example.png" /></p>
<p align="center">零钱兑换问题 II 的示例数据 </p>
<p align="center"> 14-26 &nbsp; 零钱兑换问题 II 的示例数据 </p>
<h3 id="1_2">1. &nbsp; 动态规划思路<a class="headerlink" href="#1_2" title="Permanent link">&para;</a></h3>
<p>相比于上一题,本题目标是组合数量,因此子问题变为:<strong><span class="arithmatex">\(i\)</span> 种硬币能够凑出金额 <span class="arithmatex">\(a\)</span> 的组合数量</strong>。而 <span class="arithmatex">\(dp\)</span> 表仍然是尺寸为 <span class="arithmatex">\((n+1) \times (amt + 1)\)</span> 的二维矩阵。</p>