input: Write a function to find the optimal solution to solve a knapsack problem using dynamic programming. The function should take four parameters: the capacity of the knapsack (W), the list of weights of the items (wt), the list of values of the items (val), and the number of items (n). The function should return the maximum value that can be put in the knapsack with the given capacity. If the capacity is 0 or the number of items is 0, the function should return 0. If the weight of the nth item is more than the knapsack capacity, that item cannot be included in the optimal solution. Otherwise, the function should return the maximum value between including the nth item and not including it.
  
  assert knapSack(50, [10, 20, 30], [60, 100, 120], 3) == 220
  assert knapSack(0, [10, 20, 30], [60, 100, 120], 3) == 0
  assert knapSack(50, [10, 20], [60, 100], 2) == 160
  assert knapSack(50, [], [], 0) == 0
  assert knapSack(50, [40, 50, 60], [120, 150, 180], 3) == 180
output: 
  def knapSack(W, wt, val, n):
      dp = [[0 for _ in range(W + 1)] for _ in range(n + 1)]
      
      for i in range(n + 1):
          for w in range(W + 1):
              if i == 0 or w == 0:
                  dp[i][w] = 0
              elif wt[i-1] <= w:
                  dp[i][w] = max(val[i-1] + dp[i-1][w-wt[i-1]], dp[i-1][w])
              else:
                  dp[i][w] = dp[i-1][w]
      
      return dp[n][W]
  