Buggy python submission (verdict: Time Limit Exceeded):
n,w=map(int,input().split())
l=[list(map(int,input().split())) for _ in range(n)]

dp=[[0]*(w+1) for _ in range(n+1)]
#dp:=i番目以降の商品から重さの総和がj以下となるように選んだ時の価値の総和の最大

#初期条件 dpｗｐ0で作ってるのでいらない
for j in range(w):dp[n][j] = 0

#漸化式
#dp[i][j] = dp[i+1][j] (j < w[i])
#           max(dp[i+1][j] , dp[i+1][j-w[i]]+v[i]) (otherwise)
for i in reversed(range(n)):
    for  j in range(w+1):
        if j < l[i][0]:
            dp[i][j] = dp[i+1][j]
        else:
            dp[i][j] = max(dp[i+1][j] , dp[i+1][j - l[i][0]] + l[i][1] )

print(dp[0][w])

Fixed submission:
n,w=map(int,input().split())
l=[list(map(int,input().split())) for _ in range(n)]

dp=[[0]*(w+1) for _ in range(n+1)]
#dp:=i番目以降の商品から重さの総和がj以下となるように選んだ時の価値の総和の最大

#初期条件 dpｗｐ0で作ってるのでいらない
for j in range(w):dp[n][j] = 0

#漸化式
#dp[i][j] = dp[i+1][j] (j < w[i])
#           max(dp[i+1][j] , dp[i+1][j-w[i]]+v[i]) (otherwise)
for i in reversed(range(n)):
    for  j in range(w+1):
        if j < l[i][0]:
            dp[i][j] = dp[i+1][j]
        else:
            dp[i][j] = max(dp[i+1][j] , dp[i+1][j - l[i][0]] + l[i][1] )

print(dp[0][w])

Buggy python submission (verdict: Time Limit Exceeded):
n,w=map(int,input().split())
l=[list(map(int,input().split())) for _ in range(n)]

dp=[[0]*(w+1) for _ in range(n+1)]
#dpテーブル

def rec(i,j):#再帰　i:何個目の商品を見てるか　j:残りのナップサックの容量
    if dp[i][j] != 0:#メモされてればそれを返す
        return dp[i][j]
    res = 0
    if i == n:#すべての商品を調べ終えた
        return res
    else:
        if j - l[i][0] < 0:#容量が足りない
            ans = rec(i+1,j)
        else:
            #品物を入れるときと入れないとき両方調べる
            ans = max(rec(i+1,j),rec(i+1,j-l[i][0]) + l[i][1])
    dp[i][j] = ans#メモして返す
    return dp[i][j]

print(rec(0,w))

Fixed submission:
n,w=map(int,input().split())
l=[list(map(int,input().split())) for _ in range(n)]

dp=[[0]*(w+1) for _ in range(n+1)]
#dp:=i番目以降の商品から重さの総和がj以下となるように選んだ時の価値の総和の最大

#初期条件 dpｗｐ0で作ってるのでいらない
for j in range(w):dp[n][j] = 0

#漸化式
#dp[i][j] = dp[i+1][j] (j < w[i])
#           max(dp[i+1][j] , dp[i+1][j-w[i]]+v[i]) (otherwise)
for i in reversed(range(n)):
    for  j in range(w+1):
        if j < l[i][0]:
            dp[i][j] = dp[i+1][j]
        else:
            dp[i][j] = max(dp[i+1][j] , dp[i+1][j - l[i][0]] + l[i][1] )

print(dp[0][w])

Buggy python submission (verdict: Time Limit Exceeded):
n,w=map(int,input().split())
l=[list(map(int,input().split())) for _ in range(n)]

dp=[[0]*(w+1) for _ in range(n+1)]
#dpテーブル

def rec(i,j):#再帰　i:何個目の商品を見てるか　j:残りのナップサックの容量
    if dp[i][j] != 0:#メモされてればそれを返す
        return dp[i][j]
    res = 0
    if i == n:#すべての商品を調べ終えた
        return res
    else:
        if j - l[i][0] < 0:#容量が足りない
            ans = rec(i+1,j)
        else:
            #品物を入れるときと入れないとき両方調べる
            ans = max(rec(i+1,j),rec(i+1,j-l[i][0]) + l[i][1])
    dp[i][j] = ans#メモして返す
    return dp[i][j]

print(rec(0,w))

Fixed submission:
n,w=map(int,input().split())
l=[list(map(int,input().split())) for _ in range(n)]

dp=[[0]*(w+1) for _ in range(n+1)]
#dp:=i番目以降の商品から重さの総和がj以下となるように選んだ時の価値の総和の最大

#初期条件 dpｗｐ0で作ってるのでいらない
for j in range(w):dp[n][j] = 0

#漸化式
#dp[i][j] = dp[i+1][j] (j < w[i])
#           max(dp[i+1][j] , dp[i+1][j-w[i]]+v[i]) (otherwise)
for i in reversed(range(n)):
    for  j in range(w+1):
        if j < l[i][0]:
            dp[i][j] = dp[i+1][j]
        else:
            dp[i][j] = max(dp[i+1][j] , dp[i+1][j - l[i][0]] + l[i][1] )

print(dp[0][w])