Buggy python submission (verdict: Time Limit Exceeded):
def knapsack_DP(N, W, weight, value):
    dp = [0 for _ in range(W + 1)] 
    ans=0
    for i in range(N):
        ans=max(ans, max(dp)+value[i])
        dp_tmp = [] 
        for w in range(W + 1):
            if (w >= weight[i]): 
                dp_next = max(dp[w-weight[i]] + value[i], dp[w]) 
            else:
                dp_next = dp[w] 
            dp_tmp.append(dp_next)
        dp = dp_tmp 
    return ans

if __name__=="__main__":
    N, W = map(int, input().split())
    weight = []
    value = []
    for i in range(N):
        w, v= map(int, input().split())
        weight.append(w)
        value.append(v)
    wv=((weight[i],value[i]) for i in range(N))
    wv=sorted(wv, key=lambda x:x[0])
    weight=[wv[i][0] for i in range(N)]
    value=[wv[i][1] for i in range(N)]
    print(knapsack_DP(N, W-1, weight, value))

Fixed submission:
def knapsack_DP(N, W, weight, value):
    import numpy as np
    dishes = [(weight[i], value[i]) for i in range(N)]
    dishes = sorted(dishes, key=lambda x: x[0])
    dp = np.zeros(W, dtype=int)
    ans=0
    for w, v in dishes:
        ans=max(dp[-1]+v, ans)
        np.maximum(dp[:-w] + v, dp[w:], out=dp[w:]) 
    return ans

if __name__=="__main__":
    N, W = map(int, input().split())
    weight = []
    value = []
    for i in range(N):
        w, v= map(int, input().split())
        weight.append(w)
        value.append(v)
    print(knapsack_DP(N, W, weight, value))

Buggy python submission (verdict: Time Limit Exceeded):
def knapsack_DP(N, W, weight, value):
    dp = [0 for _ in range(W + 1)] 

    for i in range(N):
        dp_tmp = [] 
        for w in range(W + 1):
            if (w >= weight[i]): 
                dp_next = max(dp[w-weight[i]] + value[i], dp[w]) 
            else:
                dp_next = dp[w] 
            dp_tmp.append(dp_next)
        dp = dp_tmp 
    return dp[-1]

if __name__=="__main__":
    N, W = map(int, input().split())
    weight = []
    value = []
    for i in range(N):
        w, v= map(int, input().split())
        weight.append(w)
        value.append(v)
    wv=((weight[i],value[i]) for i in range(N))
    wv=sorted(wv)
    weight=[wv[i][0] for i in range(N)]
    value=[wv[i][1] for i in range(N)]
    ans=0
    for i in range(1,N):
        if i==0:
          wtmp=weight[1:]
          vtmp=value[1:]
        elif i==N-1:
          wtmp=weight[:N-1]
          vtmp=value[:N-1]
        else:
          wtmp=weight[:i]+weight[i+1:]
          vtmp=value[:i]+value[i+1:]
        ans=max(knapsack_DP(N-1, W-1, wtmp, vtmp)+value[i], ans)
    print(ans)

Fixed submission:
def knapsack_DP(N, W, weight, value):
    import numpy as np
    dishes = [(weight[i], value[i]) for i in range(N)]
    dishes = sorted(dishes, key=lambda x: x[0])
    dp = np.zeros(W, dtype=int)
    ans=0
    for w, v in dishes:
        ans=max(dp[-1]+v, ans)
        np.maximum(dp[:-w] + v, dp[w:], out=dp[w:]) 
    return ans

if __name__=="__main__":
    N, W = map(int, input().split())
    weight = []
    value = []
    for i in range(N):
        w, v= map(int, input().split())
        weight.append(w)
        value.append(v)
    print(knapsack_DP(N, W, weight, value))