기간 제한이 있는 과제들에서 최대 가치를 얻는 그리디 알고리즘
과제의 기간 제한이 있고 해당 과제를 수행했을 때 얻는 가치가 서로 다르다
하루에 하나씩 과제만 처리할 수 있다.
주어진 과제들을 적절히 처리해서 최대 가치를 구한다면?
---------------------------------------------------------------------------------------------------------------------------
처음에는 과제 점수가 높은 순서대로 내림차순 정렬해서
현재 날짜랑 비교해서 처리할 수 있는 과제면 일단 가져가고
날짜랑 비교했을 때 처리할 수 없는 과제면.. 지금까지 가져간 과제들 비교해서... 실제 처리할 수 있는지 체크해보는것?
4 60
4 40
1 20
2 50
3 30
4 10
6 5
얘를 정렬하면
4 60
2 50
4 40
3 30
1 20
4 10
6 5
1일차에 4 60
2일차에 2 50
3일차에 4 40
4일차에 3 30을 가져가야하는데 3일내로 끝냈어야하니 못먹는건데
4 60, 2 50, 4 40에 대해서 2 50, 3 30, 4 40, 4 60 순으로 처리하면 처리할 수 있는 과제니까 가져가고..
이러면 1 20, 4 10은 못가져가니 6 5를 가져가면 총 185
이런 느낌으로 생각해서 억지로? 구현해봤는데 안되더라
------------------------------------------------------------------------------------------------------------------------------------
다른 방법으로 기간 제한이 빠른 순으로 오름차순 정렬
1 20
2 50
3 30
4 10
4 40
4 60
6 5
그래서 일단 빨리 끝내야하는 과제를 일단 가져가고...
1 20, 2 50, 3 30, 4 10
4 40을 가져가야하는데 현재 처리한 과제가 4개 있으므로 얘는 가져갈 수가 없다
그러면 1 20, 2 50, 3 30, 4 10 중에서 점수가 가장 작은 4 10을 버리고 4 40을 가져가는게 유리하겠지
당연하지만
1 50 2 50 3 50 4 50
이렇게 들어가있는데 4 40을 넣어야한다고 해서 점수가 가장 작은 4 50을 빼고 4 40을 넣는 것은 안해야겠지
근데 애초에 이 상황은 나올수가 없긴하다
배열에 (1,20), (2,50), ... 튜플로 들어가는데 첫번째 원소로 오름차순 정렬하면,
첫번째 원소가 같으면 두번째 원소 기준으로 오름차순 정렬하니까
다음에 들어오는 원소의 점수 값이, 같은 기간제한이라면 무조건 크게된다
--------------------------------------------------------------------------------------------------------------------------------------------
뭐 어쨌든 중요한건 기간 제한이 빠른 순으로 오름차순 정렬하고, 일단 과제를 수행하면서...
기간 제한이 다 차서 수행할 수 없는 과제가 있다면, 현재 수행한 과제 중 점수가 가장 작은걸 빼고, 이 과제를 넣어준다
여기서 "현재 수행한 과제 중 점수가 가장 작은걸 빼는것"은 우선순위 큐를 이용해서 로그 시간에 찾을 수 있다
#기간 제한이 있는 과제들을 적절하게 수행해서 최대 가치를 얻는 방법
import heapq
from sys import stdin
n = int(stdin.readline())
A = []
for _ in range(n):
x,y = map(int,stdin.readline().split())
A.append((x,y))
#기간 제한이 빠른 순으로 오름차순 정렬
A.sort()
queue = []
for x,y in A:
#일단 과제를 계속 수행하면서
heapq.heappush(queue,y)
#수행한 과제수(현재 날짜)가 현재 과제를 처리해야하는 제한보다 많아지면?
#수행한 과제들 중 점수가 가장 작은걸 제거
if len(queue) > x:
heapq.heappop(queue)
#끝나면 큐에 남아있는 점수 합이 최댓값
total = sum(queue)
print(total)
일단 큐에 계속 넣어서, 현재 처리해야하는 기간 제한보다 큐의 길이가 커지면, 큐에서 제거하는 방법 말고도
현재 큐의 길이가 처리해야하는 기간제한과 같다면, 현재 큐에서 가장 점수가 작은걸 제거하고 큐에 집어넣어도 똑같다
for x,y in A:
if len(queue) == x:
heapq.heappop(queue)
heapq.heappush(queue,y)
똑같은 문제
'알고리즘 > 그리디 알고리즘' 카테고리의 다른 글
1부터 n까지 각각 1번씩 정확히 k개의 정수만 사용해서 합을 s로 만드는 그리디 알고리즘 (0) | 2024.05.29 |
---|---|
코딩테스트 복기 - 당장 행동하지 않고 나중에 필요할 때 행동하는 그리디 알고리즘 테크닉 (0) | 2024.02.10 |
경이로운 그리디 알고리즘 5 -인접한 원소간 차이의 최댓값을 최소로 만드는 방법- (0) | 2023.11.07 |
그리디 알고리즘 연습 - 곱해서 최대가 되도록, 더해서 최소가 되도록 나누기 (0) | 2023.11.04 |
두 종류 물건을 특정 개수만큼 사면서 최소 가격에 사는 그리디 알고리즘 (0) | 2023.09.25 |