문제
수행해야 할 작업 N개 (3 ≤ N ≤ 10000)가 있다. 각각의 작업마다 걸리는 시간(1 ≤ 시간 ≤ 100)이 정수로 주어진다.
몇몇 작업들 사이에는 선행 관계라는 게 있어서, 어떤 작업을 수행하기 위해 반드시 먼저 완료되어야 할 작업들이 있다.
이 작업들은 번호가 아주 예쁘게 매겨져 있어서, K번 작업에 대해 선행 관계에 있는(즉, K번 작업을 시작하기 전에 반드시 먼저 완료되어야 하는) 작업들의 번호는 모두 1 이상 (K-1) 이하이다. 작업들 중에는, 그것에 대해 선행 관계에 있는 작업이 하나도 없는 작업이 반드시 하나 이상 존재한다. (1번 작업이 항상 그러하다)
모든 작업을 완료하기 위해 필요한 최소 시간을 구하여라. 물론, 서로 선행 관계가 없는 작업들은 동시에 수행 가능하다.
입력
첫째 줄에 N이 주어진다.
두 번째 줄부터 N+1번째 줄까지 N개의 줄이 주어진다. 2번째 줄은 1번 작업, 3번째 줄은 2번 작업, ..., N+1번째 줄은 N번 작업을 각각 나타낸다. 각 줄의 처음에는, 해당 작업에 걸리는 시간이 먼저 주어지고, 그 다음에 그 작업에 대해 선행 관계에 있는 작업들의 개수(0 ≤ 개수 ≤ 100)가 주어진다. 그리고 선행 관계에 있는 작업들의 번호가 주어진다.
출력
첫째 줄에 모든 작업을 완료하기 위한 최소 시간을 출력한다.
정답비율
41.877%
알고리즘 분류
#DP #다이나믹프로그래밍 #그래프이론 #위상정렬
import sys
input = sys.stdin.readline
n = int(input())
dp = [0] * (n+1)
for i in range(1,n+1):
tmp_lst = list(map(int, input().split()))
for num in tmp_lst[1:]:
dp[i] = max(dp[i], dp[num] + tmp_lst[0])
print(max(dp))
- DP인것만 알면 매우 쉬운문제였다. 다행히 보자마자 점화식이 떠올랐다.
- 각 작업에 선행관계에 있는 작업들 중 가장 늦게 끝나는 것에서 현재 작업이 걸리는 시간을 더하면 현재 작업이 끝나는 시간이 된다.
- 위를 이용해서 각 줄을 리스트로 받고 2번째원소(num = 1)부터 dp에 리스트 첫번째원소를 더해가며 최댓값을 구했다.
- n이 10,000인 것을보고 시간초과가 나지않을까 걱정했으나 각 줄에 주어지는 선행작업은 최대 100개이므로 많아봐야 100만의 연산이었다.
참고
'Problem Solving > Baekjoon Online Judge' 카테고리의 다른 글
< DP > 9465번 스티커 with 파이썬 (1) | 2021.05.29 |
---|---|
<정렬> 2437번 저울 with 파이썬 (0) | 2021.05.28 |
< DFS > 1967번 트리의 지름 with 파이썬 (0) | 2021.05.11 |
<정렬> 2109번 순회강연 with 파이썬 (0) | 2021.05.07 |
<정렬> 11000번 강의실 배정 with 파이썬 (0) | 2021.04.16 |