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.
Complexity
- Time: O(item_count * capacity)
- Space: O(item_count * capacity)
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))
}
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]]
Implementation notes
- Kotlin stores
weightsandvaluesas primitiveIntArrayvalues fromintArrayOf(2, 3, 4, 5)andintArrayOf(3, 4, 5, 6). val dp = Array(weights.size + 1) { IntArray(capacity + 1) }builds anArray<IntArray>with five independent rows and six zero-initialized cells per row.- The
dpbinding is aval, but table cells mutate in place throughdp[item][cap] = .... - The outer loop
for (item in 1..weights.size)maps DP rowitemtoweights[item - 1]andvalues[item - 1]; thoseIntvalues are copied into localval weightandval value. - The inner loop scans capacities with
for (cap in 0..capacity). Ifweight > cap, the cell inheritsdp[item - 1][cap]. - Otherwise the update reads only the previous row:
skip = dp[item - 1][cap],take = value + dp[item - 1][cap - weight], then storesmaxOf(skip, take). - The trace records row states after each item:
[0, 0, 3, 3, 3, 3],[0, 0, 3, 4, 4, 7],[0, 0, 3, 4, 5, 7], and[0, 0, 3, 4, 5, 7]. println(dp[weights.size][capacity])prints7, andtableString(dp)formats the full table for the second output line.