input: Write a function to solve a knapsack problem using dynamic programming. The function should take as input a list of items where each item is represented as a tuple (value, weight), and an integer representing the capacity of the knapsack. The function should return the maximum value that can be obtained by selecting items without exceeding the knapsack's capacity.
  
  def knapSack(W, wt, val, n):
      if n == 0 or W == 0:
          return 0
      if wt[n-1] > W:
          return knapSack(W, wt, val, n-1)
      else:
          return max(val[n-1] + knapSack(W-wt[n-1], wt, val, n-1), knapSack(W, wt, val, n-1))
  
  assert knapSack(50, [10, 20, 30], [60, 100, 120], 3) == 220
  assert knapSack(10, [1, 2, 3], [10, 15, 40], 3) == 65
  assert knapSack(7, [1, 3, 4], [1, 4, 5], 3) == 9
  assert knapSack(0, [10, 20, 30], [60, 100, 120], 3) == 0
  assert knapSack(50, [], [], 0) == 0
output: def knapSack(W, items):
      n = len(items)
      dp = [[0] * (W + 1) for _ in range(n + 1)]
      
      for i in range(1, n + 1):
          for w in range(1, W + 1):
              if items[i-1][1] <= w:
                  dp[i][w] = max(dp[i-1][w], items[i-1][0] + dp[i-1][w-items[i-1][1]])
              else:
                  dp[i][w] = dp[i-1][w]
      
      return dp[n][W]