# your code goes here
def solve(T):
# 한정 패키지: (이름, 가격, 토큰, 제한수량)
P = [
("월정액", 5900, 30, 6),
("심월보물집", 12000, 68, 1),
("봄", 4700, 24, 1),
("유리", 4700, 24, 1),
("옥구금빛", 12000, 68, 2),
("옥구울린", 12000, 68, 2),
("정찬금빛", 37000, 198, 2),
("정찬군가", 25000, 128, 2),
("현방지원", 25000, 128, 2),
]
# 무제한 깡충전: (이름, 가격, 토큰)
U = [
("각인60", 1200, 6),
("각인300", 5900, 30),
("각인980", 19000, 98),
("각인1980", 37000, 198),
("각인3280", 65000, 328),
("각인6480", 119000, 648),
]
# 한정 패키지를 낱개 리스트로 펼치기
L = []
for n, c, t, k in P:
for _ in range(k):
L.append((n, c, t))
INF = float("inf")
dp = [INF] * (T + 1)
par = [None] * (T + 1) # 백트래킹용 기록장
dp[0] = 0
# 1. 한정 패키지 (중복 방지를 위해 역방향 순회)
for n, c, t in L:
for w in range(T, -1, -1):
if dp[w] != INF:
nxt = min(T, w + t)
if dp[w] + c < dp[nxt]:
dp[nxt] = dp[w] + c
par[nxt] = (w, n, c, t)
# 2. 무제한 깡충전 (중복 구매 가능하므로 정방향 순회)
for n, c, t in U:
for w in range(T + 1):
if dp[w] != INF:
nxt = min(T, w + t)
if dp[w] + c < dp[nxt]:
dp[nxt] = dp[w] + c
par[nxt] = (w, n, c, t)
# 3. 백트래킹으로 구매 리스트 복원
path = []
cur = T
while cur > 0 and par[cur]:
pw, n, c, t = par[cur]
path.append((n, c, t))
cur = pw
return dp[T], path[::-1]
# 실행 결과 출력
for T in [980, 1600, 2200]:
cost, ans = solve(T)
print(f"[{T} 토큰] 최소비용: {cost:,}원")
for n, c, t in ans:
print(f" - {n}: {c:,}원 ({t}t)")
print()
IyB5b3VyIGNvZGUgZ29lcyBoZXJlCmRlZiBzb2x2ZShUKToKICAgICMg7ZWc7KCVIO2MqO2CpOyngDogKOydtOumhCwg6rCA6rKpLCDthqDtgbAsIOygnO2VnOyImOufiSkKICAgIFAgPSBbCiAgICAgICAgKCLsm5TsoJXslaEiLCA1OTAwLCAzMCwgNiksCiAgICAgICAgKCLsi6zsm5Trs7TrrLzsp5EiLCAxMjAwMCwgNjgsIDEpLAogICAgICAgICgi67SEIiwgNDcwMCwgMjQsIDEpLAogICAgICAgICgi7Jyg66asIiwgNDcwMCwgMjQsIDEpLAogICAgICAgICgi7Jil6rWs6riI67mbIiwgMTIwMDAsIDY4LCAyKSwKICAgICAgICAoIuyYpeq1rOyauOumsCIsIDEyMDAwLCA2OCwgMiksCiAgICAgICAgKCLsoJXssKzquIjruZsiLCAzNzAwMCwgMTk4LCAyKSwKICAgICAgICAoIuygleywrOq1sOqwgCIsIDI1MDAwLCAxMjgsIDIpLAogICAgICAgICgi7ZiE67Cp7KeA7JuQIiwgMjUwMDAsIDEyOCwgMiksCiAgICBdCiAgICAjIOustOygnO2VnCDquaHstqnsoIQ6ICjsnbTrpoQsIOqwgOqyqSwg7Yag7YGwKQogICAgVSA9IFsKICAgICAgICAoIuqwgeyduDYwIiwgMTIwMCwgNiksCiAgICAgICAgKCLqsIHsnbgzMDAiLCA1OTAwLCAzMCksCiAgICAgICAgKCLqsIHsnbg5ODAiLCAxOTAwMCwgOTgpLAogICAgICAgICgi6rCB7J24MTk4MCIsIDM3MDAwLCAxOTgpLAogICAgICAgICgi6rCB7J24MzI4MCIsIDY1MDAwLCAzMjgpLAogICAgICAgICgi6rCB7J24NjQ4MCIsIDExOTAwMCwgNjQ4KSwKICAgIF0KCiAgICAjIO2VnOyglSDtjKjtgqTsp4Drpbwg64Kx6rCcIOumrOyKpO2KuOuhnCDtjrzsuZjquLAKICAgIEwgPSBbXQogICAgZm9yIG4sIGMsIHQsIGsgaW4gUDoKICAgICAgICBmb3IgXyBpbiByYW5nZShrKToKICAgICAgICAgICAgTC5hcHBlbmQoKG4sIGMsIHQpKQoKICAgIElORiA9IGZsb2F0KCJpbmYiKQogICAgZHAgPSBbSU5GXSAqIChUICsgMSkKICAgIHBhciA9IFtOb25lXSAqIChUICsgMSkgICMg67Cx7Yq4656Y7YK57JqpIOq4sOuhneyepQogICAgZHBbMF0gPSAwCgogICAgIyAxLiDtlZzsoJUg7Yyo7YKk7KeAICjspJHrs7Ug67Cp7KeA66W8IOychO2VtCDsl63rsKntlqUg7Iic7ZqMKQogICAgZm9yIG4sIGMsIHQgaW4gTDoKICAgICAgICBmb3IgdyBpbiByYW5nZShULCAtMSwgLTEpOgogICAgICAgICAgICBpZiBkcFt3XSAhPSBJTkY6CiAgICAgICAgICAgICAgICBueHQgPSBtaW4oVCwgdyArIHQpCiAgICAgICAgICAgICAgICBpZiBkcFt3XSArIGMgPCBkcFtueHRdOgogICAgICAgICAgICAgICAgICAgIGRwW254dF0gPSBkcFt3XSArIGMKICAgICAgICAgICAgICAgICAgICBwYXJbbnh0XSA9ICh3LCBuLCBjLCB0KQoKICAgICMgMi4g66y07KCc7ZWcIOq5oey2qeyghCAo7KSR67O1IOq1rOunpCDqsIDriqXtlZjrr4DroZwg7KCV67Cp7ZalIOyInO2ajCkKICAgIGZvciBuLCBjLCB0IGluIFU6CiAgICAgICAgZm9yIHcgaW4gcmFuZ2UoVCArIDEpOgogICAgICAgICAgICBpZiBkcFt3XSAhPSBJTkY6CiAgICAgICAgICAgICAgICBueHQgPSBtaW4oVCwgdyArIHQpCiAgICAgICAgICAgICAgICBpZiBkcFt3XSArIGMgPCBkcFtueHRdOgogICAgICAgICAgICAgICAgICAgIGRwW254dF0gPSBkcFt3XSArIGMKICAgICAgICAgICAgICAgICAgICBwYXJbbnh0XSA9ICh3LCBuLCBjLCB0KQoKICAgICMgMy4g67Cx7Yq4656Y7YK57Jy866GcIOq1rOunpCDrpqzsiqTtirgg67O17JuQCiAgICBwYXRoID0gW10KICAgIGN1ciA9IFQKICAgIHdoaWxlIGN1ciA+IDAgYW5kIHBhcltjdXJdOgogICAgICAgIHB3LCBuLCBjLCB0ID0gcGFyW2N1cl0KICAgICAgICBwYXRoLmFwcGVuZCgobiwgYywgdCkpCiAgICAgICAgY3VyID0gcHcKCiAgICByZXR1cm4gZHBbVF0sIHBhdGhbOjotMV0KCgojIOyLpO2WiSDqsrDqs7wg7Lac66ClCmZvciBUIGluIFs5ODAsIDE2MDAsIDIyMDBdOgogICAgY29zdCwgYW5zID0gc29sdmUoVCkKICAgIHByaW50KGYiW3tUfSDthqDtgbBdIOy1nOyGjOu5hOyaqToge2Nvc3Q6LH3sm5AiKQogICAgZm9yIG4sIGMsIHQgaW4gYW5zOgogICAgICAgIHByaW50KGYiICAtIHtufToge2M6LH3sm5AgKHt0fXQpIikKICAgIHByaW50KCk=