Files
hello-algo/zh-hant/docs/chapter_greedy/exercises.md
T
krahets 22e898c9af build
2026-07-19 07:20:08 +08:00

88 lines
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
comments: true
---
# 15.6   練習
## 15.6.1   知識鞏固
### 1.   每次選最大硬幣一定最好嗎
硬幣面值為 `[1, 7, 10]`,目標金額為 14。
<!-- numbered-subquestions -->
1. 按“每次取不超過剩餘金額的最大面值”執行,寫出所取硬幣;
2. 是否存在使用更少硬幣的方案?如果存在,請寫出一種;如果不存在,請說明理由;
3. 這能否說明該貪婪策略對任意硬幣面值都正確?
??? success "參考答案"
1. 貪婪依次選擇 `10 + 1 + 1 + 1 + 1`,共 5 枚硬幣。
2. 存在使用更少硬幣的方案:`7 + 7`,只需 2 枚硬幣。
3. 不能。這個反例說明,對任意硬幣面值,每次選擇當前能取的最大面值並不一定得到最少硬幣數;
眼前最大的選擇可能破壞後續更好的組合。
### 2. &nbsp; 背包應該先裝哪件物品
一個容量為 4 千克的背包中可以裝入以下物品,物品允許只取一部分,
所取價值與重量成正比:
- 物品 A:重量 4 千克,價值 20;
- 物品 B:重量 3 千克,價值 18。
<!-- numbered-subquestions -->
1. 兩件物品每千克的價值分別是多少?應先裝哪一件?
2. 按分數背包的貪婪策略裝滿背包,最終價值是多少?
3. 在物品可以切分、背包限制總重量的情況下,選擇物品時應該比較總價值還是每千克價值?為什麼?
??? success "參考答案"
1. A 每千克價值為 `20 ÷ 4 = 5`B 每千克價值為 `18 ÷ 3 = 6`
因此應先裝單位價值更高的 B。
2. 先裝入全部 B,佔用 3 千克、獲得價值 18;剩餘 1 千克容量,
再裝入 1 千克 A,獲得價值 5。最終價值為 `18 + 5 = 23`
3. 背包限制的是總重量,而且物品可以切分,所以應比較單位重量的價值。
A 的總價值雖然更高,但每千克價值低於 B;若先裝滿 A,只能得到價值 20。
### 3. &nbsp; 兩個指標下一步怎樣移動
隔板高度為 `[1, 8, 6, 2, 5]`,用首尾雙指標尋找最大容量。
容量等於“兩塊隔板中較短者的高度 × 兩塊隔板的下標距離”。
<!-- numbered-subquestions -->
1. 初始時左指標在下標 0、右指標在下標 4,當前容量是多少?下一步應移動哪個指標?
2. 按照第 1 問的選擇移動一次後,兩個指標分別位於哪個下標?此時容量是多少?下一步又應移動哪個指標?
3. 在當前一對隔板中,可以移動較短隔板對應的指標,也可以移動較長隔板對應的指標。哪一種移動仍有可能得到更大的容量?為什麼?
??? success "參考答案"
1. 當前容量為 `min(1, 5) × (4 - 0) = 4`。左側隔板較短,因此移動左指標。
2. 移動左指標後,兩個指標分別位於下標 1 和 4。當前容量為
`min(8, 5) × (4 - 1) = 15`。右側隔板較短,因此下一步移動右指標。
3. 移動較短隔板對應的指標,才仍有可能得到更大的容量。移動較長隔板後,兩塊隔板的距離一定縮短,而容器高度仍受未移動的短板限制,
只可能不變或變小。因此容量不可能超過移動前;只有移動短板,才有機會遇到更高的隔板。
## 15.6.2 &nbsp; 程式設計練習
### 1. &nbsp; 分數背包
給定等長陣列 `wgt``val`,其中 `wgt[i] > 0``val[i] >= 0`,背包容量 `cap >= 0`
每種物品只有一件,但允許只裝入其中一部分,
獲得的價值按所裝重量佔該物品總重量的比例計算。請使用貪婪演算法,
並以實數返回背包能夠獲得的最大總價值。
??? tip "解題提示"
1. 先計算每件物品的單位重量價值 val[i] / wgt[i],除法結果要保留小數
2. 單位價值越高的物品越先裝入背包
3. 若剩餘容量小於當前物品重量,就裝入恰好填滿背包的部分並結束