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.
Perl DSA Implementation
basic.pl
use strict;
use warnings;
sub row_string { return "[" . join(", ", @_) . "]"; }
sub table_string { return "[" . join(", ", map { row_string(@$_) } @_) . "]"; }
my @weights = (2, 3, 4, 5);
my @values = (3, 4, 5, 6);
my $capacity = 5;
my @dp = map { [(0) x ($capacity + 1)] } 0..scalar(@weights);
for my $item (1..scalar(@weights)) {
my $weight = $weights[$item - 1];
my $value = $values[$item - 1];
for my $cap (0..$capacity) {
if ($weight > $cap) {
$dp[$item][$cap] = $dp[$item - 1][$cap];
} else {
my $skip = $dp[$item - 1][$cap];
my $take = $value + $dp[$item - 1][$cap - $weight];
$dp[$item][$cap] = $skip > $take ? $skip : $take;
}
}
}
print "$dp[scalar(@weights)][$capacity]\n";
print table_string(@dp) . "\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