Buggy python submission (verdict: Runtime Error):
N = int(input())
"""
dp[i][j] -> i番目の人間までみる。j人が積むときの最小値。

"""
HP = [list(map(int,input().split())) for _ in range(N)]
HP.sort(key=lambda x:x[0]+x[1])
dp = [[float("INF")]*(N+1) for _ in range(N)]
for i in range(N):
    dp[i][0] = 0
dp[0][1] = HP[1][1]
for i in range(1,N):
    for j in range(1,N+1):
        if dp[i-1][j-1] <= HP[i][0]:
            dp[i][j] = min(dp[i-1][j],dp[i-1][j-1]+HP[i][1])
        else:
            dp[i][j] = dp[i-1][j]
for j in range(N,-1,-1):
    if dp[-1][j] != float("INF"):
        print(j)
        break


Fixed submission:
N = int(input())
men = []
for _ in range(N):
    H,P = map(int,input().split())
    men.append((H,P,H+P))
men.sort(key=lambda x: x[2])

maxH = max(men)[0]
inf = maxH+1
#dp[i][j] -> i人目までみたとき、j人が座布団を積む場合の最小枚数
dp = [[-1]*(N+1) for _ in range(N+1)]
dp[0][0] = 0
for i in range(1,N+1):
    h,p,a = men[i-1]
    for j in range(1,N+1):
        if 0 <= dp[i-1][j-1] <= h:
            if dp[i-1][j] == -1:
                dp[i][j] = dp[i-1][j-1]+p
            else:
                dp[i][j] = min(dp[i-1][j],dp[i-1][j-1]+p)
        else:
            dp[i][j] = dp[i-1][j]

for j in range(N,-1,-1):
    if dp[-1][j] != -1:
        print(j)
        break

Buggy python submission (verdict: Runtime Error):
N = int(input())
HP = [list(map(int,input().split())) for _ in range(N)]
HP.sort(key=lambda x: x[0]+x[1])
ceil = max(HP,key=lambda x: x[0])[0]
#dp[i][j] -> i人目まで見る。j人積むときの、座布団の枚数の最小値
dp = [ceil+1]*(N+1)
ans = 0
for i in range(N+1):
    dp[i][0] = 0
for i in range(N):
    h,p = HP[i]
    for j in range(N,0,-1):
        if dp[j-1]<=h:
            dp[j] = min(dp[j],dp[j-1]+p)
            ans = max(ans,j)

print(ans)

Fixed submission:
N = int(input())
men = []
for _ in range(N):
    H,P = map(int,input().split())
    men.append((H,P,H+P))
men.sort(key=lambda x: x[2])

maxH = max(men)[0]
inf = maxH+1
#dp[i][j] -> i人目までみたとき、j人が座布団を積む場合の最小枚数
dp = [[-1]*(N+1) for _ in range(N+1)]
dp[0][0] = 0
for i in range(1,N+1):
    h,p,a = men[i-1]
    for j in range(1,N+1):
        if 0 <= dp[i-1][j-1] <= h:
            if dp[i-1][j] == -1:
                dp[i][j] = dp[i-1][j-1]+p
            else:
                dp[i][j] = min(dp[i-1][j],dp[i-1][j-1]+p)
        else:
            dp[i][j] = dp[i-1][j]

for j in range(N,-1,-1):
    if dp[-1][j] != -1:
        print(j)
        break

Buggy python submission (verdict: Time Limit Exceeded):
N = int(input())
HP = [list(map(int,input().split())) for _ in range(N)]
HP.sort(key=lambda x: x[0]+x[1])
#dp[i][j] -> i人目まで見る。j人積むときの、座布団の枚数の最小値
dp = [[float("INF")]*(N+1) for _ in range(N+1)]
ans = 0
for i in range(N+1):
    dp[i][0] = 0
for i in range(1,N+1):
    h,p = HP[i-1]
    for j in range(1,N+1):
        if dp[i-1][j-1]<=h:
            dp[i][j] = min(dp[i-1][j],dp[i-1][j-1]+p)
            ans = max(ans,j)
        else:
            dp[i][j] = dp[i-1][j]

print(ans)

Fixed submission:
N = int(input())
men = []
for _ in range(N):
    H,P = map(int,input().split())
    men.append((H,P,H+P))
men.sort(key=lambda x: x[2])

maxH = max(men)[0]
inf = maxH+1
#dp[i][j] -> i人目までみたとき、j人が座布団を積む場合の最小枚数
dp = [[-1]*(N+1) for _ in range(N+1)]
dp[0][0] = 0
for i in range(1,N+1):
    h,p,a = men[i-1]
    for j in range(1,N+1):
        if 0 <= dp[i-1][j-1] <= h:
            if dp[i-1][j] == -1:
                dp[i][j] = dp[i-1][j-1]+p
            else:
                dp[i][j] = min(dp[i-1][j],dp[i-1][j-1]+p)
        else:
            dp[i][j] = dp[i-1][j]

for j in range(N,-1,-1):
    if dp[-1][j] != -1:
        print(j)
        break

Buggy python submission (verdict: Time Limit Exceeded):
"""
dp[i][j] -> i人目までみる。j人が座布団を積むときの、最小の座布団の枚数
"""
N = int(input())
men = []
for _ in range(N):
    h,p=map(int,input().split())
    men.append((h,p))

men.sort(key=lambda x: sum(x))
ceil = max(men,key=lambda x: x[0])[0]+1
dp = [[float("INF")for _ in range(N+1)] for _ in range(N+1)]
for i in range(N+1):
    dp[i][0] = 0

for i in range(1,N+1):
    h,p = men[i-1][0],men[i-1][1]
    for j in range(1,i+1):
        if dp[i-1][j-1] <= h:
            dp[i][j] = min(dp[i-1][j],dp[i-1][j-1]+p)
        else:
            dp[i][j] = dp[i-1][j]
        
for j in range(N,-1,-1):
    if dp[-1][j] != float("INF"):
        print(j)
        break



Fixed submission:
N = int(input())
men = []
for _ in range(N):
    H,P = map(int,input().split())
    men.append((H,P,H+P))
men.sort(key=lambda x: x[2])

maxH = max(men)[0]
inf = maxH+1
#dp[i][j] -> i人目までみたとき、j人が座布団を積む場合の最小枚数
dp = [[-1]*(N+1) for _ in range(N+1)]
dp[0][0] = 0
for i in range(1,N+1):
    h,p,a = men[i-1]
    for j in range(1,N+1):
        if 0 <= dp[i-1][j-1] <= h:
            if dp[i-1][j] == -1:
                dp[i][j] = dp[i-1][j-1]+p
            else:
                dp[i][j] = min(dp[i-1][j],dp[i-1][j-1]+p)
        else:
            dp[i][j] = dp[i-1][j]

for j in range(N,-1,-1):
    if dp[-1][j] != -1:
        print(j)
        break

Buggy python submission (verdict: Time Limit Exceeded):
N = int(input())
men = []
hCeil = 0
for _ in range(N):
    h,p = map(int,input().split())
    men.append((h+p,h,p))
    hCeil = max(hCeil,h)
men.sort()
hCeil += 1
"""
dp[i][j][0] -> i人目までみる&j人が積むときの最小枚数
dp[i][j][1] -> 積んだかどうかのフラグ
"""
dp = [[(hCeil,0) for i in range(N+1)] for _ in range(N+1)]
for i in range(N+1):
    dp[i][0] = (0,1)
for i in range(1,N+1):
    h,p = men[i-1][1],men[i-1][2]
    for j in range(1,i+1):
        if dp[i-1][j-1][0]<=h:
            nxP = min(dp[i-1][j][0],dp[i-1][j-1][0]+p)
            dp[i][j] = (nxP,1)
        else:
            dp[i][j] = dp[i-1][j]

for j in range(N,-1,-1):
    if dp[-1][j][1] != 0:
        print(j)
        break


Fixed submission:
N = int(input())
men = []
for _ in range(N):
    H,P = map(int,input().split())
    men.append((H,P,H+P))
men.sort(key=lambda x: x[2])

maxH = max(men)[0]
inf = maxH+1
#dp[i][j] -> i人目までみたとき、j人が座布団を積む場合の最小枚数
dp = [[-1]*(N+1) for _ in range(N+1)]
dp[0][0] = 0
for i in range(1,N+1):
    h,p,a = men[i-1]
    for j in range(1,N+1):
        if 0 <= dp[i-1][j-1] <= h:
            if dp[i-1][j] == -1:
                dp[i][j] = dp[i-1][j-1]+p
            else:
                dp[i][j] = min(dp[i-1][j],dp[i-1][j-1]+p)
        else:
            dp[i][j] = dp[i-1][j]

for j in range(N,-1,-1):
    if dp[-1][j] != -1:
        print(j)
        break

Buggy python submission (verdict: Time Limit Exceeded):
N = int(input())
men = []
for _ in range(N):
    H,P = map(int,input().split())
    men.append((H,P,H+P))
men.sort(key=lambda x: x[2])

dp = [[float("INF")]*(N+1) for _ in range(N+1)]
dp[0][0] = 0
for i in range(1,N+1):
    h,p,a = men[i-1]
    for j in range(1,N+1):
        if dp[i-1][j-1] <= h:
            dp[i][j] = min(dp[i-1][j],dp[i-1][j-1]+p)
        else:
            dp[i][j] = dp[i-1][j]

for j in range(N,-1,-1):
    if dp[-1][j] != float("INF"):
        print(j)
        break


Fixed submission:
N = int(input())
men = []
for _ in range(N):
    H,P = map(int,input().split())
    men.append((H,P,H+P))
men.sort(key=lambda x: x[2])

maxH = max(men)[0]
inf = maxH+1
#dp[i][j] -> i人目までみたとき、j人が座布団を積む場合の最小枚数
dp = [[-1]*(N+1) for _ in range(N+1)]
dp[0][0] = 0
for i in range(1,N+1):
    h,p,a = men[i-1]
    for j in range(1,N+1):
        if 0 <= dp[i-1][j-1] <= h:
            if dp[i-1][j] == -1:
                dp[i][j] = dp[i-1][j-1]+p
            else:
                dp[i][j] = min(dp[i-1][j],dp[i-1][j-1]+p)
        else:
            dp[i][j] = dp[i-1][j]

for j in range(N,-1,-1):
    if dp[-1][j] != -1:
        print(j)
        break

Buggy python submission (verdict: Runtime Error):
N = int(input())
men = []
for _ in range(N):
    H,P = map(int,input().split())
    men.append((H,P,H+P))
men.sort(key=lambda x: x[2])

inf = max(H)+1
dp = [[inf]*(N+1) for _ in range(N+1)]
dp[0][0] = 0
for i in range(1,N+1):
    h,p,a = men[i-1]
    for j in range(1,N+1):
        if dp[i-1][j-1] <= h:
            dp[i][j] = min(dp[i-1][j],dp[i-1][j-1]+p)
        else:
            dp[i][j] = dp[i-1][j]

for j in range(N,-1,-1):
    if dp[-1][j] != inf:
        print(j)
        break


Fixed submission:
N = int(input())
men = []
for _ in range(N):
    H,P = map(int,input().split())
    men.append((H,P,H+P))
men.sort(key=lambda x: x[2])

maxH = max(men)[0]
inf = maxH+1
#dp[i][j] -> i人目までみたとき、j人が座布団を積む場合の最小枚数
dp = [[-1]*(N+1) for _ in range(N+1)]
dp[0][0] = 0
for i in range(1,N+1):
    h,p,a = men[i-1]
    for j in range(1,N+1):
        if 0 <= dp[i-1][j-1] <= h:
            if dp[i-1][j] == -1:
                dp[i][j] = dp[i-1][j-1]+p
            else:
                dp[i][j] = min(dp[i-1][j],dp[i-1][j-1]+p)
        else:
            dp[i][j] = dp[i-1][j]

for j in range(N,-1,-1):
    if dp[-1][j] != -1:
        print(j)
        break