Problem p03008 (Python) — buggy submission, verdict: Time Limit Exceeded

import math
import os
import sys

if os.getenv("LOCAL"):
    sys.stdin = open("_in.txt", "r")

sys.setrecursionlimit(2147483647)
INF = float("inf")

N = int(sys.stdin.readline())
GA, SA, BA = list(map(int, sys.stdin.readline().split()))
GB, SB, BB = list(map(int, sys.stdin.readline().split()))

values = []
weights = []
if GB / GA > 1:
    values.append(GB - GA)
    weights.append(GA)
if SB / SA > 1:
    values.append(SB - SA)
    weights.append(SA)
if BB / BA > 1:
    values.append(BB - BA)
    weights.append(BA)
# dp[i]: 重さ i 以下で選ぶのの価値の最大値
dp = [0] * (N + 1)
dp[0] = N
if values:
    for i in range(1, N + 1):
        x = dp[i - 1]
        for w, v in zip(weights, values):
            if i - w >= 0:
                x = max(x, dp[i - w] + v)
        dp[i] = x
    N = dp[N]

values = []
weights = []
if GA / GB > 1:
    values.append(GA - GB)
    weights.append(GB)
if SA / SB > 1:
    values.append(SA - SB)
    weights.append(SB)
if BA / BB > 1:
    values.append(BA - BB)
    weights.append(BB)
# dp[i]: 重さ i 以下で選ぶのの価値の最大値
dp = [0] * (N + 1)
dp[0] = N
if len(values) == 3:
    for i in range(1, N + 1):
        x = dp[i - 1]
        for w, v in zip(weights, values):
            if i - w >= 0:
                x = max(x, dp[i - w] + v)
        dp[i] = x
    N = dp[N]
if len(values) == 2:
    w1, w2 = weights
    v1, v2 = values
    if (v1 + w1) / w1 < (v2 + w2) / w2:
        v1, v2 = v2, v1
        w1, w2 = w2, w1
    c1 = N // w1
    c2 = (N - w1 * c1) // w2
    ret = N + v1 * c1 + v2 * c2
    while c1 >= 0:
        a = N - w1 * c1 - w2 * c2
        c1 -= max(1, math.ceil((w2 - a) / w1))
        c2 = (N - w1 * c1) // w2
        ret = max(ret, N + v1 * c1 + v2 * c2)
        if w1 * c1 + w2 * c2 == N:
            break
    N = ret
if len(values) == 1:
    N += N // weights[0] * values[0]
print(int(N))


Error: TLE

Fixed submission:

import os
import sys

if os.getenv("LOCAL"):
    sys.stdin = open("_in.txt", "r")

sys.setrecursionlimit(2147483647)
INF = float("inf")

N = int(sys.stdin.readline())
GA, SA, BA = list(map(int, sys.stdin.readline().split()))
GB, SB, BB = list(map(int, sys.stdin.readline().split()))

values = []
weights = []
if GB / GA > 1:
    values.append(GB - GA)
    weights.append(GA)
if SB / SA > 1:
    values.append(SB - SA)
    weights.append(SA)
if BB / BA > 1:
    values.append(BB - BA)
    weights.append(BA)
# dp[i]: 重さ i 以下で選ぶのの価値の最大値
dp = [0] * (N + 1)
dp[0] = N
if values:
    for i in range(1, N + 1):
        x = dp[i - 1]
        for w, v in zip(weights, values):
            if i - w >= 0:
                x = max(x, dp[i - w] + v)
        dp[i] = x
    N = dp[N]

values = []
weights = []
if GA / GB > 1:
    values.append(GA - GB)
    weights.append(GB)
if SA / SB > 1:
    values.append(SA - SB)
    weights.append(SB)
if BA / BB > 1:
    values.append(BA - BB)
    weights.append(BB)
# dp[i]: 重さ i 以下で選ぶのの価値の最大値
dp = [0] * (N + 1)
dp[0] = N
if values:
    for i in range(1, N + 1):
        x = dp[i - 1]
        for w, v in zip(weights, values):
            if i - w >= 0:
                x = max(x, dp[i - w] + v)
        dp[i] = x
    N = dp[N]
print(int(N))