Buggy python submission (verdict: Time Limit Exceeded):
N, W = map(int, input().split())
wv = [list(map(int, input().split())) for _ in range(N)]
ws = [x[0] for x in wv]
vs = [x[1] for x in wv]

dp = [{} for _ in range(100)]
def dfs(weight=0, depth=N - 1):
    if dp[depth].get(weight) is not None:
        return dp[depth][weight]

    if depth == -1:
        dp[depth][weight] = 0
        return 0

    if weight + ws[depth] <= W:
        result = max(dfs(weight, depth - 1), dfs(weight + ws[depth], depth - 1) + vs[depth])
    else:
        result = dfs(weight, depth - 1)
    dp[depth][weight] = result
    return result

print(dfs())


Fixed submission:
N, W = map(int, input().split())
wv = [list(map(int, input().split())) for _ in range(N)]
ws = [x[0] for x in wv]
vs = [x[1] for x in wv]

dp = [[None] * (10**5 + 1) for _ in range(100 + 1)]
# def dfs(weight=0, depth=N - 1):
#     if dp[depth][weight] is not None:
#         return dp[depth][weight]
#
#     if depth == -1:
#         dp[depth][weight] = 0
#         return 0
#
#     if weight + ws[depth] <= W:
#         result = max(dfs(weight, depth - 1), dfs(weight + ws[depth], depth - 1) + vs[depth])
#     else:
#         result = dfs(weight, depth - 1)
#     dp[depth][weight] = result
#     return result
#
# print(dfs())

dp[-1] = [0] * len(dp[-1])
for depth in range(0, N):
    for weight in range(10**5 + 1):
        v = dp[depth - 1][weight]
        if weight + ws[depth] <= W:
            dp[depth][weight] = max(v, dp[depth - 1][weight + ws[depth]] + vs[depth])
        else:
            dp[depth][weight] = v

print(dp[N - 1][0])

Buggy python submission (verdict: Time Limit Exceeded):
N, W = map(int, input().split())
wv = [list(map(int, input().split())) for _ in range(N)]
ws = [x[0] for x in wv]
vs = [x[1] for x in wv]

dp = [{} for _ in range(100)]
def dfs(weight=0, depth=N - 1):
    if dp[depth].get(weight) is not None:
        return dp[depth][weight]

    if depth == -1:
        return 0

    if weight + ws[depth] <= W:
        result = max(dfs(weight + ws[depth], depth - 1) + vs[depth], dfs(weight, depth - 1))
    else:
        result = dfs(weight, depth - 1)
    dp[depth][weight] = result
    return result

print(dfs())


Fixed submission:
N, W = map(int, input().split())
wv = [list(map(int, input().split())) for _ in range(N)]
ws = [x[0] for x in wv]
vs = [x[1] for x in wv]

dp = [[None] * (10**5 + 1) for _ in range(100 + 1)]
# def dfs(weight=0, depth=N - 1):
#     if dp[depth][weight] is not None:
#         return dp[depth][weight]
#
#     if depth == -1:
#         dp[depth][weight] = 0
#         return 0
#
#     if weight + ws[depth] <= W:
#         result = max(dfs(weight, depth - 1), dfs(weight + ws[depth], depth - 1) + vs[depth])
#     else:
#         result = dfs(weight, depth - 1)
#     dp[depth][weight] = result
#     return result
#
# print(dfs())

dp[-1] = [0] * len(dp[-1])
for depth in range(0, N):
    for weight in range(10**5 + 1):
        v = dp[depth - 1][weight]
        if weight + ws[depth] <= W:
            dp[depth][weight] = max(v, dp[depth - 1][weight + ws[depth]] + vs[depth])
        else:
            dp[depth][weight] = v

print(dp[N - 1][0])

Buggy python submission (verdict: Runtime Error):
N, W = map(int, input().split())
wv = [list(map(int, input().split())) for _ in range(N)]
ws = [x[0] for x in wv]
vs = [x[1] for x in wv]

dp = [[None] * 10**5 for _ in range(100)]
def dfs(weight=0, depth=N - 1):
    if dp[weight][depth] is not None:
        return dp[weight][depth]

    if depth == -1:
        return 0

    if weight + ws[depth] <= W:
        result = max(dfs(weight + ws[depth], depth - 1) + vs[depth], dfs(weight, depth - 1))
    else:
        result = dfs(weight, depth - 1)
    dp[weight][depth] = result
    return result

print(dfs())


Fixed submission:
N, W = map(int, input().split())
wv = [list(map(int, input().split())) for _ in range(N)]
ws = [x[0] for x in wv]
vs = [x[1] for x in wv]

dp = [[None] * (10**5 + 1) for _ in range(100 + 1)]
# def dfs(weight=0, depth=N - 1):
#     if dp[depth][weight] is not None:
#         return dp[depth][weight]
#
#     if depth == -1:
#         dp[depth][weight] = 0
#         return 0
#
#     if weight + ws[depth] <= W:
#         result = max(dfs(weight, depth - 1), dfs(weight + ws[depth], depth - 1) + vs[depth])
#     else:
#         result = dfs(weight, depth - 1)
#     dp[depth][weight] = result
#     return result
#
# print(dfs())

dp[-1] = [0] * len(dp[-1])
for depth in range(0, N):
    for weight in range(10**5 + 1):
        v = dp[depth - 1][weight]
        if weight + ws[depth] <= W:
            dp[depth][weight] = max(v, dp[depth - 1][weight + ws[depth]] + vs[depth])
        else:
            dp[depth][weight] = v

print(dp[N - 1][0])