Recursion and Dynamic Programming
0/1 Knapsack (Small)
Fill a small 0/1 knapsack table where each row decides whether one more item is available.
Algorithm
@steps
- Create a table with one extra row for using zero items.
- Process the four items in fixed order.
- For each capacity, inherit when the item is too heavy.
- Otherwise compare
skipandtakefrom the previous row. - Print the best value and the full deterministic table. @end @complexity
- Time: O(item_count * capacity)
- Space: O(item_count * capacity) @end
state transition
`dp[i][w]` compares skipping item `i` with taking it and reading the remaining capacity from the previous row.
Scala DSA Implementation
basic.scala
object Main extends App {
def rowString(row: Array[Int]): String = row.mkString("[", ", ", "]")
def tableString(table: Array[Array[Int]]): String = table.map(rowString).mkString("[", ", ", "]")
val weights = Array(2, 3, 4, 5)
val values = Array(3, 4, 5, 6)
val capacity = 5
val dp = Array.fill(weights.length + 1, capacity + 1)(0)
for (item <- 1 to weights.length) {
val weight = weights(item - 1)
val value = values(item - 1)
for (cap <- 0 to capacity) {
if (weight > cap) dp(item)(cap) = dp(item - 1)(cap)
else {
val skip = dp(item - 1)(cap)
val take = value + dp(item - 1)(cap - weight)
dp(item)(cap) = math.max(skip, take)
}
}
}
println(dp(weights.length)(capacity))
println(tableString(dp))
}
@end @output 7 [[0, 0, 0, 0, 0, 0], [0, 0, 3, 3, 3, 3], [0, 0, 3, 4, 4, 7], [0, 0, 3, 4, 5, 7], [0, 0, 3, 4, 5, 7]] @end