You can reduce memory usage by making the following observations:
At any moment, your code uses only no more than two levels of the ptrarray array.
If you iterate from the largest to the lowest index in each layer, you can overwrite the previous layer. This way you only need one array.
Here is the pseudocode with this optimization:
max_weight = new int[max_capacity + 1](false) max_weight[0] = true for weight in weights: for capacity in [max_capacity ... weight]: max_weight[capacity] = max(max_weight[capacity], max_weight[capacity - weight] + weight
This requires O(max_capacity) memory (instead of O(max_capacity * number_of_items) ).
A few additional optimizations: you can use a boolean array (to indicate whether the sum i reachable) and select the largest achievable amount at the end, rather than store the largest amount less than or equal to i addition, you can use std::bitset instead of the boolean array to get the time complexity of O(max_capacity * num_items / world_len) (where world_len is the size of the largest integer type on which the machine can perform logical operations). Adding one weight will look like reachable |= (reachable << weight) .
So, the final version looks like this:
reachable = bitset(max_capacity + 1) reachable[0] = true for weight in weights: reachable |= reachable << weight return highest set bit of reachable
The code becomes much simpler and more efficient in this way (the time complexity is technically the same, but in practice it is much faster).
There is a caveat here: you need to know the size of std::bitset at compile time, so if this is not possible, you will need a different bit set implementation.
source share