'''simple docstring'''




def _lowercase						(   lowerCamelCase__				,     lowerCamelCase__				,     lowerCamelCase__				,     lowerCamelCase__    )       ->							int:





       """simple docstring"""


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

def _lowercase						(   lowerCamelCase__				,     lowerCamelCase__				,     lowerCamelCase__				,     lowerCamelCase__    )       ->							Tuple:





       """simple docstring"""


       __UpperCAmelCase	:					Tuple												=		[[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_:
                            __UpperCAmelCase	:					List[str]												=		max(val[i - 1] + dp[i - 1][w_ - wt[i - 1]]				,     dp[i - 1][w_]    )
                     else:
                            __UpperCAmelCase	:					Union[str, Any]												=		dp[i - 1][w_]

       return dp[n][w_], dp

def _lowercase						(   lowerCamelCase__				,     lowerCamelCase__				,     lowerCamelCase__    )       ->							Tuple:





       """simple docstring"""


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

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

       __UpperCAmelCase	:					int												=		knapsack(__snake_case				,     __snake_case				,     __snake_case				,     __snake_case    )
       __UpperCAmelCase	:					set												=		set()
       _construct_solution(__snake_case				,     __snake_case				,     __snake_case				,     __snake_case				,     __snake_case    )

       return optimal_val, example_optional_set

def _lowercase						(   lowerCamelCase__				,     lowerCamelCase__				,     lowerCamelCase__				,     lowerCamelCase__				,     lowerCamelCase__    )       ->							Dict:





       """simple docstring"""


       if i > 0 and j > 0:
              if dp[i - 1][j] == dp[i][j]:
                     _construct_solution(__snake_case				,     __snake_case				,     i - 1				,     __snake_case				,     __snake_case    )
              else:
                     optimal_set.add(__snake_case    )
                     _construct_solution(__snake_case				,     __snake_case				,     i - 1				,     j - wt[i - 1]				,     __snake_case    )


if __name__ == "__main__":
   _a :						Optional[int]							= [3, 2, 4, 4]
   _a :						Tuple							= [4, 3, 2, 3]
   _a :						Any							= 4
   _a :						int							= 6
   _a :						Tuple							= [[0] * (w + 1)] + [[0] + [-1] * (w + 1) for _ in range(n + 1)]
   _a				,       _a :						Union[str, Any]							= 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 :						Optional[int]							= 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)










"""simple docstring"""
def 				_snake_case      (   __snake_case							:      list[list[int]]						, __snake_case							:      int						, __snake_case							:      int						, __snake_case							:      list[int]   ):




   """simple docstring"""







   if graph[path[curr_ind - 1]][next_ver] == 0:
      return False

   # 2. Validate that next vertex is not already in path
   return not any(vertex == next_ver for vertex in path   )

def 				_snake_case      (   __snake_case							:      list[list[int]]						, __snake_case							:      list[int]						, __snake_case							:      int   ):




   """simple docstring"""







   if curr_ind == len(__snake_case   ):
      # return whether path exists between current and starting vertices
      return graph[path[curr_ind - 1]][path[0]] == 1

   # Recursive Step
   for next_ver in range(0						, len(__snake_case   )   ):
      if valid_connection(__snake_case						, __snake_case						, __snake_case						, __snake_case   ):
         # Insert current vertex  into path as next transition
         _lowerCamelCase	:					List[str]   =		next_ver
         # Validate created path
         if util_hamilton_cycle(__snake_case						, __snake_case						, curr_ind + 1   ):
            return True
         # Backtrack
         _lowerCamelCase	:					Tuple   =		-1
   return False





def 				_snake_case      (   __snake_case							:      list[list[int]]						, __snake_case							:      int = 0   ):




   """simple docstring"""







   _lowerCamelCase	:					Any   =		[-1] * (len(__snake_case   ) + 1)
   # initialize start and end of path with starting index
   _lowerCamelCase	:					Optional[int]   =		start_index
   # evaluate and if we find answer return path either return empty array
   return path if util_hamilton_cycle(__snake_case						, __snake_case						, 1   ) else []

