728x90
23843번: 콘센트
광재는 전자기기 대여사업을 시작했다. 퇴근하기 전에 다음날 손님들에게 빌려줄 N개의 전자기기를 충전하려 한다. 사용 가능한 콘센트는 M개가 있고, 성능은 모두 동일하다. 전자기기들은 한
www.acmicpc.net
📄 문제개요
- 전자 기기를 충전하려고 할때, 사용가능한 콘센트의 개수는 M개가 있고, 성능은 모두 동일하다.
- 전자기기들은 한번에 하나의 콘센트에서만 충전 가능하고, 충전에 필요한 시간은 2^k 형태이다.
- 광재의 빠른 퇴근을 위해 모든 전자기기를 충전하기 위한 최소 시간을 구하여라.
🤔 문제분석
- 충전시간이 가장 오래걸리는 전자기기부터 콘센트에 꽂는다.
- 충전시간이 다 끝나면 해당 전자기기를 빼고, 다음의 전자기기를 넣는다.
- 전자기기가 빠지는경우는, 현재 전자기기중에서 가장 충전시간이 작은 전자기기가 다음에 빠질 것이다.
- 따라서 가장 작은 전자기기를 기준으로 시간을 카운팅 한다.
📝 의사코드
- 전자기기를 충전시간을 기준으로 내림차순 정렬한다.
- 전자기기중 가장 충전시간이 짧은 시간을 구하기위하여 우선순위 큐를 사용한다.
- 전자기기를 넣을 수 있으면 전자기기를 가장 오래걸리는 기기부터 콘센트에 넣는다.
- 전자기기를 넣을 수 없다면 아래의 로직으로 전자기기를 빼고 넣는다.
- 충전시간이 가장 적은 시간을 기준으로 모든 전자기기의 시간을 줄인다.
- 충전시간이 0이된 전자기기는 큐에서 모조리 뺀다.
- 큐가 비었으니 전자기기를 넣는다.
- 전자기기를 모두 순회한뒤, 남은 전자기기가 있다면 충전시간을 계산하며 빼낸다.
💻 코드
import heapq, sys
input = sys.stdin.readline
N, M = map(int, input().split())
devices = list(map(int, input().split()))
devices.sort(key=lambda x:-x)
queue = []
ans = 0
for device in devices:
if M > len(queue):
heapq.heappush(queue, device)
else:
time = queue[0]
ans += time
for i in range(len(queue)):
queue[i] -= time
while queue and queue[0] == 0:
heapq.heappop(queue)
heapq.heappush(queue, device)
while queue:
time = queue[0]
ans += time
for i in range(len(queue)):
queue[i] -= time
while queue and queue[0] == 0:
heapq.heappop(queue)
print(ans)
🎯 피드백 및 개선사항
- 현재의 알고리즘은 O(N*M)으로 M이 만약 증가하게된다면, 원하는 시간복잡도로 문제를 해결 할 수 없다.
- 아래의 문제는 O(N*Log(M))으로 문제를 해결 하였다.
❓다른사람은 어떻게 풀었을까?
- 큐를 일정 크기를 유지하면서 가장 작은 장치에, 가장 큰 장치를 넣어가며 업데이트한다.
import sys
import heapq
def input():
return sys.stdin.readline().rstrip()
N,M = map(int,input().split())
arr = list(map(int,input().split()))
max_heap = [0]*M
arr.sort(reverse=True)
for t in arr:
last = heapq.heappop(max_heap)
heapq.heappush(max_heap,last+t)
print(max(max_heap))
728x90
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 1285번 : 동전 뒤집기 (2) | 2023.12.02 |
---|---|
[백준] 3109번 : 빵집 (2) | 2023.12.02 |
[백준] 11000번 : 강의실배정 (1) | 2023.11.29 |
[백준] 1700번 : 멀티텝 스케줄링 (1) | 2023.11.27 |
[백준] 16681번 : 등산 (2) | 2023.11.27 |