---
# System prepended metadata

title: 第七題

---

# 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 分 (有寫點東西, 名稱不要太奇怪)

