11from functools import cache
22
33
4- def knapsack_memoized (weights : list [int ], values : list [int ], capacity : int ) -> int :
4+ def knapsack_memoized (
5+ weights : list [int ], values : list [int ], capacity : int
6+ ) -> int :
57 """
68 Solve 0/1 knapsack using memoization without global state.
79
@@ -19,6 +21,8 @@ def knapsack_memoized(weights: list[int], values: list[int], capacity: int) -> i
1921 65
2022 >>> knapsack_memoized([], [], 5)
2123 0
24+ >>> knapsack_memoized([2, 3, 4], [4, 5, 6], 0)
25+ 0
2226 """
2327
2428 if len (weights ) != len (values ):
@@ -27,16 +31,29 @@ def knapsack_memoized(weights: list[int], values: list[int], capacity: int) -> i
2731 n = len (weights )
2832
2933 @cache
30- def dp (i : int , remaining : int ) -> int :
31- if i == n or remaining == 0 :
34+ def dp (index : int , remaining : int ) -> int :
35+ """
36+ Recursive helper function for knapsack memoization.
37+
38+ Args:
39+ index: current item index
40+ remaining: remaining capacity of knapsack
41+
42+ Returns:
43+ Maximum value achievable from current state
44+
45+ Note:
46+ This function is internally tested via knapsack_memoized doctests.
47+ """
48+ if index == n or remaining == 0 :
3249 return 0
3350
34- if weights [i ] > remaining :
35- return dp (i + 1 , remaining )
51+ if weights [index ] > remaining :
52+ return dp (index + 1 , remaining )
3653
3754 return max (
38- dp (i + 1 , remaining ),
39- values [i ] + dp (i + 1 , remaining - weights [i ]),
55+ dp (index + 1 , remaining ),
56+ values [index ] + dp (index + 1 , remaining - weights [index ]),
4057 )
4158
4259 return dp (0 , capacity )
0 commit comments