We are given an array of positive weights cost where
cost[i]
represents the cost of fillingi + 1
kg's of oranges in a bag (0-based indexing). We need to find the minimum cost to buy exactlyw
kg's of oranges assuming an infinite supply of eachi + 1
kg's of oranges.
How could we derive the sub-problems for this problem and how exactly in combination with those we get the solution to our final problem?
Hence, after going through a dynamic programming question on SO, I first tried to implement the recursive brute force solution to get an idea of what subproblems are we solving.
import math
def solve(n, cost, w, curr_cost, stack, dp):
if w < 0:
return
if w == 0:
print(stack, curr_cost)
res = min(res, curr_cost)
return
for i in range(n):
stack.append(i + 1)
solve(n, cost, w - (i + 1), curr_cost + cost[i], stack, dp)
stack.pop()
n = 5
cost = [20, 10, 4, 50, 100]
w = 5
res = math.inf
dp = [math.inf for _ in range(w + 1)]
solve(n, cost, w, 0, [], dp)
print(res)
Now, I cannot memoize this solution using which we can try to build a bottom-up solution. For example, if we make a 2D
grid of dimensions n x w
(after going through some hints), we know for row 0
i.e., n=0
, all the cells in that row will be cost[0] * w
as we have packets of only 1
kg of oranges. And for column 1
, all the cells in that column would be cost[0]
as we need exactly 1
kg of oranges which is possible only with a packet of size 1
kg. Now, how do I use this information to calculate the values of other cells?
1 2 3 4 5 <- w
0 20 40 60 80 100
1 20 - - - -
2 20 - - - -
3 20 - - - -
4 20 - - - -
^n
i.e., writing the brute force recursive solution, identifying the smaller subproblems, and then building up a bottom-up solution and how exactly these subproblems combine that give us a final correct solution.