# PDSA 期中考第七題
## 解答
```
function SOLUTION(items, M):
###### 建立 dp ######
n = length(items)
dp = array of size (n+1) x (M+1) # 2D dp
for w from 0 to M:
dp[0][w] = 0
for i from 1 to n:
for w from 0 to M:
if w_i > w:
dp[i][w] = dp[i-1][w]
else:
dp[i][w] = max( dp[i-1][w], v_i + dp[i-1][w - w_i] )
###### 獲得 collection 中的 items ######
w = M
collection = []
for i from n to 1:
if dp[i][w] != dp[i-1][w]:
add item i to collection
w = w - w_i
return dp[n][M], collection
```
## 講解
1. 建立一個 2D table, dp[*i*][*w*] 是指前面 *i* 個 items 和 剩餘容量 *w* 時所能達到的最大 value
```
n = length(items)
dp = array of size (n + 1) × (M + 1)
```
2. 在沒有 item 時, 能獲得的 max value = 0
```
for w from 0 to M:
dp[0][w] = 0
```
3. 如果 w~i~ 大於剩餘容量 w 時, item~i~不會被放入,否則將會被拿取。跟加入前的 max value 比較後將新的 max value 存入 dp,一直算到 dp[n][M]。
```
for i from 1 to n:
for w from 0 to M:
if w_i > w:
dp[i][w] = dp[i-1][w]
else:
dp[i][w] = max( dp[i-1][w], v_i + dp[i-1][w - w_i] )
```
4. 如果不等式成立, 代表 item~i~ 有被選中。將 item~i~ 加入 collection 中, 扣除 w~i~,一直算到 i = 1 得到完整 collection。
```
w = M
collection = []
for i from n to 1:
if dp[i][w] != dp[i-1][w]:
add item i to collection
w = w - w_i
```
## 常見錯誤
1) dp table size 怎麼樣都不會是 w x v !! (批改時會對照 for loop 中使用的 indexing 邏輯)
3) dp table initialize: 在一開始, value 應該是0, 不會是1)
4) recursive 實作 for loop 更新邏輯錯誤, 但有寫出正確的 recursive relation 會部分給分
6) 變數命名請使用題目中有定義的變數、助教看得懂的命名方式或有另外附上說明 :)
## 配分
依照題義應該解出 "Which items to include in the collection ......", 但鑒於本題的作答情形過於慘烈, 本題給分放寬至只需要**實作完 dp table 即可獲得滿分**。
dp table: size (3 分) + initialize (2 分)
中間recursive 判斷 (8 分)(如果有寫出正確的recursive relation 但實作有錯誤部分給分 3 分)
變數名稱: 2 分 (有寫點東西, 名稱不要太奇怪)