






def _UpperCAmelCase   (	a						:	Tuple  ,					a						:	Dict  ,					a						:	Union[str, Any]  ,					a						:	Optional[Any] ):
							global f  # a global dp table for knapsack
							if f[i][j] < 0:
														if j < wt[i - 1]:
																					snake_case__	  =       mf_knapsack(i - 1  ,					a  ,					a  ,					a )
														else:
																					snake_case__	  =       max(
																					    mf_knapsack(i - 1  ,					a  ,					a  ,					a )  ,					mf_knapsack(i - 1  ,					a  ,					a  ,					j - wt[i - 1] ) + val[i - 1]  ,					)
														snake_case__	  =       val
							return f[i][j]

def _UpperCAmelCase   (	a						:	str  ,					a						:	Tuple  ,					a						:	Optional[Any]  ,					a						:	int ):
							snake_case__	  =       [[0] * (w + 1) for _ in range(n + 1 )]

							for i in range(1  ,					n + 1 ):
														for w_ in range(1  ,					w + 1 ):
																					if wt[i - 1] <= w_:
																												snake_case__	  =       max(val[i - 1] + dp[i - 1][w_ - wt[i - 1]]  ,					dp[i - 1][w_] )
																					else:
																												snake_case__	  =       dp[i - 1][w_]

							return dp[n][w_], dp

def _UpperCAmelCase   (	a						:	int  ,					a						:	list  ,					a						:	list ):
							if not (isinstance(a  ,					(list, tuple) ) and isinstance(a  ,					(list, tuple) )):
														raise ValueError(
														    """Both the weights and values vectors must be either lists or tuples""" )

							snake_case__	  =       len(a )
							if num_items != len(a ):
														snake_case__	  =       (
														    """The number of weights must be the same as the number of values.\n"""
														    F'''But got {num_items} weights and {len(a )} values'''
														)
														raise ValueError(a )
							for i in range(a ):
														if not isinstance(wt[i]  ,					a ):
																					snake_case__	  =       (
																					    """All weights must be integers but got weight of """
																					    F'''type {type(wt[i] )} at index {i}'''
																					)
																					raise TypeError(a )

							snake_case__  , snake_case__	  =       knapsack(a  ,					a  ,					a  ,					a )
							snake_case__	  =       set()
							_construct_solution(a  ,					a  ,					a  ,					a  ,					a )

							return optimal_val, example_optional_set

def _UpperCAmelCase   (	a						:	list  ,					a						:	list  ,					a						:	int  ,					a						:	int  ,					a						:	set ):
							# for the current item i at a maximum weight j to be part of an optimal subset,
							# the optimal value at (i, j) must be greater than the optimal value at (i-1, j).
							# where i - 1 means considering only the previous items at the given maximum weight
							if i > 0 and j > 0:
														if dp[i - 1][j] == dp[i][j]:
																					_construct_solution(a  ,					a  ,					i - 1  ,					a  ,					a )
														else:
																					optimal_set.add(a )
																					_construct_solution(a  ,					a  ,					i - 1  ,					j - wt[i - 1]  ,					a )


if __name__ == "__main__":
	a__       =     [3, 2, 4, 4]
	a__       =     [4, 3, 2, 3]
	a__       =     4
	a__       =     6
	a__       =     [[0] * (w + 1)] + [[0] + [-1] * (w + 1) for _ in range(n + 1)]
	a__  ,		a__       =     knapsack(w, wt, val, n)
	print(optimal_solution)
	print(mf_knapsack(n, wt, val, w))  # switched the n and w

	# testing the dynamic programming problem with example
	# the optimal subset for the above example are items 3 and 4
	a__  ,		a__       =     knapsack_with_example_solution(w, wt, val)
	assert optimal_solution == 8
	assert optimal_subset == {3, 4}
	print("""optimal_value = """, optimal_solution)
	print("""An optimal subset corresponding to the optimal value""", optimal_subset)








def _UpperCAmelCase   (	a						:	int = 400_0000 ):
							snake_case__	  =       [0, 1]
							snake_case__	  =       0
							while fib[i] <= n:
														fib.append(fib[i] + fib[i + 1] )
														if fib[i + 2] > n:
																					break
														i += 1
							snake_case__	  =       0
							for j in range(len(a ) - 1 ):
														if fib[j] % 2 == 0:
																					total += fib[j]

							return total


if __name__ == "__main__":
	print(F'''{solution() = }''')
