fun knapsack(capacity, items) = let (* which of these two "packs" -- that is, value, item list pair -- is the most valuable? *) fun maxPack(pack1 as (v1, items1), pack2 as (v2, items2)) = ?? val (has, get, put) = makeTable([]); (* find the best list of items with the given capacity; the result is a pair, the total value and the list of items *) fun K(0) = (0, []) | K(W) = if ?? (* check to see if we've tried this capacity before *) then ?? else let (* find the most valuable list of items within this capacity. n is our position in the original list. *) fun checkItems(n, []) = (0, []) | checkItems(n, (w, v)::rest) = if w < W (* if item n can fit in the remaining capacity, would we be better off to take it or not? *) then let val (vv, ws) = ?? ; in maxPack((vv + v, n::ws), ??) end else checkItems(n+1, rest); val best = checkItems(1, items); in (put(W, best); best) end; in K(capacity) end; (* given (18, [(7, 20), (12, 3), (3, 6)]) we would interpret this to mean we have a knapsack of capacity 18; there is an item weighing 7 units with 20 units of value, another weighing 12 units with 3 units of value, and a third weighing 3 units with 6 units of value. A solution would be (46, [1, 1, 3]) meaning, if we took two instances of the first item and on instance of the third, we would have weight 7 + 7 + 3 = 17 < 18 and value 20 + 20 + 6 = 46 That's the best we can fit. *)