input: def optimal_knapsack_solution(items: List[Tuple[int, int]], capacity: int) -> int:
      """
      Finds the optimal solution to solve a knapsack problem using dynamic programming.
      The function takes a list of items where each item is a tuple containing its value and weight.
      It also takes the capacity of the knapsack as input.
  
      >>> optimal_knapsack_solution([(60, 10), (100, 20), (120, 30)], 50)
      220
      """
output:     dp = [0] * (capacity + 1)
      for value, weight in items:
          for j in range(capacity, weight - 1, -1):
              dp[j] = max(dp[j], dp[j - weight] + value)
      return dp[capacity]