[BaekJoon 13904 : Data Structure, Python] - 과제
2021, Dec 05
백준 13904 과제 : 골드 3
Solution
import sys
input = sys.stdin.readline
from heapq import *
from collections import defaultdict
n = int(input())
tasks = []
howmany = defaultdict(int)
for _ in range(n):
d, s = map(int, input().split())
heappush(tasks, [-s, d])
howmany[d] = 0 # 해당 마감일의 과제가 몇 번 count 됐는지 기록
cnt, max_d, total = 0, 0, 0
while tasks:
cur_s, cur_d = heappop(tasks)
if cnt >= cur_d: # 현재까지 완료한 과제 수가 마감일보다 많을 때
tmp_cnt = 0
for tmp_d in range(1, max_d + 1): # 현재 마감일보다 마감일이 같거나 높은 모든 과제에 대해 양보 가능한지 확인
tmp_cnt += howmany[tmp_d]
if tmp_d >= cur_d and tmp_cnt >= tmp_d: # 양보 불가
break
else:
total += cur_s # for-else 구문 : 현재 마감일 이전에 완료된 모든 과제가 양보 가능한 경우
howmany[cur_d] += 1
cnt += 1
else: # 타겟 과제의 마감일이 완료한 과제수보다 클 때(아직 마감기한이 남은 경우), 그냥 넣어줌
total += cur_s
howmany[cur_d] += 1
max_d = max(max_d, cur_d)
cnt += 1
print(-total)
풀이과정 및 느낀점
- 그리디 + 우선순위 큐를 사용해 문제를 풀었다.
- 우선 점수가 높은 순대로 최대힙을 만든다
- 그리디하게 점수 높은 과제 순서대로 total 점수에 합산하는데, 대신 아래의 조건을 따른다
- 현재까지 완료한 과제 수가 타겟 과제의 마감일보다 큰 경우
- 타겟 과제보다 마감일이 같거나 높은 모든 과제가 양보가능한지 확인 (각 마감일까지 합산한 과제 수가 마감일보다 크거나 같으면 양보 불가)
- 타겟 과제의 마감일이 현재까지 완료된 과제수보다 크면 그냥 바로 total 점수에 합산함.
- 현재까지 완료한 과제 수가 타겟 과제의 마감일보다 큰 경우
높은 점수 순대로 그리디하게 합산한다는 점까지는 알겠는데, 마감일까지 반영하는 조건을 생각해내는 게 까다로웠다. 다른 사람들 풀이를 보니 내 풀이보다 2배 이상 빠른 풀이가 있던데, 못 알아듣겠다.