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.
Kotlin DSA Implementation
basic.kt
fun rowString(row: IntArray): String = row.joinToString(prefix = "[", postfix = "]")
fun tableString(table: Array<IntArray>): String = table.joinToString(prefix = "[", postfix = "]") { rowString(it) }
fun main() {
val weights = intArrayOf(2, 3, 4, 5)
val values = intArrayOf(3, 4, 5, 6)
val capacity = 5
val dp = Array(weights.size + 1) { IntArray(capacity + 1) }
for (item in 1..weights.size) {
val weight = weights[item - 1]
val value = values[item - 1]
for (cap in 0..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] = maxOf(skip, take)
}
}
}
println(dp[weights.size][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