[백준] 1781 : 컵라면 - Python

Chooooo·2024년 7월 1일
0

알고리즘/백준

목록 보기
198/204

문제

상욱 조교는 동호에게 N개의 문제를 주고서, 각각의 문제를 풀었을 때 컵라면을 몇 개 줄 것인지 제시 하였다. 하지만 동호의 찌를듯한 자신감에 소심한 상욱 조교는 각각의 문제에 대해 데드라인을 정하였다.

문제 번호 1 2 3 4 5 6 7
데드라인 1 1 3 3 2 2 6
컵라면 수 6 7 2 1 4 5 1
위와 같은 상황에서 동호가 2, 6, 3, 1, 7, 5, 4 순으로 숙제를 한다면 2, 6, 3, 7번 문제를 시간 내에 풀어 총 15개의 컵라면을 받을 수 있다.

문제는 동호가 받을 수 있는 최대 컵라면 수를 구하는 것이다. 위의 예에서는 15가 최대이다.

문제를 푸는데는 단위 시간 1이 걸리며, 각 문제의 데드라인은 N이하의 자연수이다. 또, 각 문제를 풀 때 받을 수 있는 컵라면 수와 최대로 받을 수 있는 컵라면 수는 모두 231보다 작은 자연수이다.

내 코드

import heapq
import sys
sys.stdin = open("input.txt", "rt")

# 컵라면.
# n개의 문제. 각각의 문제를 풀었을 때 컵라면을 몇 개 줄 것인지 정해져있음
# 각 문제 별로 데드라인이 있음
# 받을 수 있는 최대 컵라면 수 구하기.

# N <= 200,000 -> N^2으로 풀 수 없음
# 현재 상황마다. 가능한 문제들 중에... 최대를 뽑아야겠다.
# -> 뒤에서부터 판단하면 되겠다.


n = int(input())
data = []
heap = []
for _ in range(n):
    deadline, cnt = map(int, input().split()) # 데드라인, 컵라면 수
    heapq.heappush(heap, (-deadline, cnt)) # 데드라인은 내림차순, 개수는 오름차순 우선순위

temp = []
res = 0
max_deadline = -heap[0][0] # 가장 큰 데드라인 값
for deadline in range(max_deadline, 0, -1): # 매일 하루에 한 개씩 처리할 수 있으므로
    while heap and abs(heap[0][0]) >= deadline: # 현재 뽑기가 가능한 경우 : 데드라인 이상
        _, cnt = heapq.heappop(heap) # 개수만 필요
        heapq.heappush(temp, -cnt) # 꺼내야 할 컵라면은 역시 최대개수임
    # print(f"현재 deadline : {deadline} 가능한 cnt : {temp[:]}")
    if temp:
        cnt = heapq.heappop(temp)
        res += -cnt

print(res)

코멘트

문제 접근할 때 데드라인이 늦은 문제부터 처리하는 그리디 알고리즘을 생각했어야 함.
-> 또한 최대 힙을 사용하여 효율적으로 문제 선택.

하루에 한 문제, 목표는 받을 수 있는 최대 컵라면 수 구하기

우선순위를 데드라인 큰 순, 개수 큰 순으로 담는다. (사실 개수 오름차순으로 해버렸는데 상관없음 데드라인이 중요)

데드라인이 가장 늦은 날짜부터 1까지 역순으로 반복하는데, 각 날짜에 대해 현재 날짜 이하의 데드라인을 가진 모든 문제를 고려 대상에 넣는다.

고려 대상 중 가장 많은 컵라면을 주는 문제 선택.

그리디 + 우선순위 큐로 문제 해결 가능

profile
back-end, 지속 성장 가능한 개발자를 향하여

0개의 댓글