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.
Bash DSA Implementation
basic.sh
row_string() {
local out="["
local first=1
for value in "$@"; do
if (( first )); then first=0; else out+=", "; fi
out+="$value"
done
out+="]"
printf '%s' "$out"
}
weights=(2 3 4 5)
values=(3 4 5 6)
capacity=5
declare -A dp
for ((item=0; item<=4; item++)); do
for ((cap=0; cap<=capacity; cap++)); do dp[$item,$cap]=0; done
done
for ((item=1; item<=4; item++)); do
weight=${weights[item-1]}
value=${values[item-1]}
for ((cap=0; cap<=capacity; cap++)); do
if (( weight > cap )); then
dp[$item,$cap]=${dp[$((item-1)),$cap]}
else
skip=${dp[$((item-1)),$cap]}
take=$((value + dp[$((item-1)),$((cap-weight))]))
if (( take > skip )); then dp[$item,$cap]=$take; else dp[$item,$cap]=$skip; fi
fi
done
done
echo "${dp[4,5]}"
printf '['
for ((item=0; item<=4; item++)); do
if (( item > 0 )); then printf ', '; fi
row=()
for ((cap=0; cap<=capacity; cap++)); do row+=("${dp[$item,$cap]}"); done
row_string "${row[@]}"
done
printf ']\n'
@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