https://www.acmicpc.net/problem/2637
2637번: 장난감 조립
첫째 줄에는 자연수 N(3 ≤ N ≤ 100)이 주어지는데, 1부터 N-1까지는 기본 부품이나 중간 부품의 번호를 나타내고, N은 완제품의 번호를 나타낸다. 그리고 그 다음 줄에는 자연수 M(3 ≤ M ≤ 100)이 주
www.acmicpc.net
위상정렬과 DP를 함께 수행하는 문제입니다. 골드 2문제라서 그런지 난이도가 꽤 있었습니다. 단순히 위상정렬만 실행을 하면 메모리 초과가 떠서 DP까지 함께 수행을 해줘야합니다. 먼저 기초 부품들을 따로 저장해두고 각 부품별 필요한 기초 부품들을 dp 배열에 저장해둡니다. dp[i][j]는 j를 만들기 위한 i번째 기초 부품의 개수를 저장하고 있습니다. 위상정렬을 해주면서 각 부품에 필요한 기초 부품의 수를 저장해두고 in_node가 0이 되는 순간이 곧 필요한 기초 부품 수 계산이 끝난 것을 의미하므로 큐에 넣어줍니다.
import sys
from collections import defaultdict, deque
input = sys.stdin.readline
graph = defaultdict(list)
n = int(input())
m = int(input())
in_node = [0] * (n + 1)
element = []
for _ in range(m):
# x를 만들기 위해 y가 k개 필요하다.
x, y, k = tuple(map(int, input().split()))
graph[y].append((x, k))
in_node[x] += 1
# in_node가 0인 애들은 기초 부품이다.
for i in range(1, n + 1):
if in_node[i] == 0:
element.append(i)
# dp[i][j]:j를 만들기 위해 필요한 i의 개수
dp = [
[0] * (n + 1)
for _ in range(len(element))
]
# 기초 부붐들을 세팅한다.
for idx, el in enumerate(element):
dp[idx][el] += 1
q = deque([el for el in element])
while q:
cur = q.pop()
# 다음 노드를 만들기 위해 필요한 개수
for next, cnt in graph[cur]:
# next를 만들기 위해 필요한 i번째 기초 원소를 저장한다.
for i in range(len(element)):
dp[i][next] += cnt * dp[i][cur]
in_node[next] -= 1
if in_node[next] == 0:
q.append(next)
for i in range(len(element)):
print(element[i], dp[i][n])
'문제 해결 > BOJ' 카테고리의 다른 글
[백준] 나눌 수 있는 부분 수열 (0) | 2023.02.16 |
---|---|
[백준] 계보 복원가 호석 (0) | 2023.02.15 |
[백준] 문자열 생성 (0) | 2023.02.14 |
[백준] 크게 만들기 (0) | 2023.02.13 |
[백준] Coins (0) | 2023.02.13 |