mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-23 11:46:08 +00:00
88 lines
3.9 KiB
Markdown
88 lines
3.9 KiB
Markdown
---
|
||
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. 背包應該先裝哪件物品
|
||
|
||
一個容量為 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. 兩個指標下一步怎樣移動
|
||
|
||
隔板高度為 `[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 程式設計練習
|
||
|
||
### 1. 分數背包
|
||
|
||
給定等長陣列 `wgt` 和 `val`,其中 `wgt[i] > 0`、`val[i] >= 0`,背包容量 `cap >= 0`。
|
||
每種物品只有一件,但允許只裝入其中一部分,
|
||
獲得的價值按所裝重量佔該物品總重量的比例計算。請使用貪婪演算法,
|
||
並以實數返回背包能夠獲得的最大總價值。
|
||
|
||
??? tip "解題提示"
|
||
|
||
1. 先計算每件物品的單位重量價值 val[i] / wgt[i],除法結果要保留小數
|
||
2. 單位價值越高的物品越先裝入背包
|
||
3. 若剩餘容量小於當前物品重量,就裝入恰好填滿背包的部分並結束
|