그리디(Greedy)

  • 현재 상황에서 가장 최적의 답을 선택하는 알고리즘
  • 최종적으로 최적의 해가 나온다는 보장이 없다.
  • 탐욕 선택 속성(greedy choice property), 최적 부분 구조(optimal substructure) 특성의 문제에 적합하다.
    • 최적 부분 구조 예시 : (서울과 대구의 최단 경로) + (대구와 부산의 최단 경로) = 서울과 부산의 최단 경로
  • 한 번의 선택이 다음 선택에 무관해야 하고, 매 순간의 최적해가 문제에 대한 최적해여야 한다.
  • 활용 예시
    • 거스름돈, 다익스트라 알고리즘, 허프만 코드, 크루스칼 알고리즘

 

그리디 문제 - 11047번 동전 0

https://www.acmicpc.net/problem/11047

 

11047번: 동전 0

첫째 줄에 N과 K가 주어진다. (1 ≤ N ≤ 10, 1 ≤ K ≤ 100,000,000) 둘째 줄부터 N개의 줄에 동전의 가치 Ai가 오름차순으로 주어진다. (1 ≤ Ai ≤ 1,000,000, A1 = 1, i ≥ 2인 경우에 Ai는 Ai-1의 배수)

www.acmicpc.net

 

# n, k = 10, 4200  # 동전 종류, 구하려는 값 - 동전의 최소 개수 구하기
# arr = [1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 50000]
n, k = map(int, input().split())
arr = []
for _ in range(n):
    arr.append(int(input()))
arr = sorted(arr, reverse=True)
cnt = res = 0

for x in arr:
    if k >= x:
        cnt = k // x
        res += cnt
        k = k - (x * cnt)
    if k <= 0:
        break
print(res)

 

그리디 문제 - 1931번 회의실 배정

- 최대 회의 횟수 구하기

https://www.acmicpc.net/problem/1931

 

1931번: 회의실 배정

(1,4), (5,7), (8,11), (12,14) 를 이용할 수 있다.

www.acmicpc.net

n = int(input())  # 회의 수 - 회의가 겹치지 않게 진행할 수 있는 회의 최대 개수 구하기
arr = [[0] * 2 for _ in range(n)]
for i in range(n):
    a, b = map(int, input().split())
    arr[i][0] = a # 회의 시작 시간
    arr[i][1] = b # 회의 끝나는 시간

#n = 11
#arr = [[1, 1], [1, 5], [0, 6], [5, 7], [3, 8], [5, 9], [6, 10], [8, 11], [8, 12], [2, 13], [12, 14]]
#n = 3
#arr = [[1,1],[1,1],[0,1]]
arr.sort(key=lambda x: (x[1], x[0])) # 두번째 값이 같은 경우, 첫번째 값으로 오름차순
time = cnt = start = end = 0

for element in arr:
    start = element[0]
    end = element[1]
    if time <= start:
        time = end
        cnt += 1
print(cnt)

 

그리디 문제 - 11000번 강의실 배정

- 최소 강의실 개수 구하기

https://www.acmicpc.net/problem/11000

 

11000번: 강의실 배정

첫 번째 줄에 N이 주어진다. (1 ≤ N ≤ 200,000) 이후 N개의 줄에 Si, Ti가 주어진다. (0 ≤ Si < Ti ≤ 109)

www.acmicpc.net

# 최소 강의실 개수 구하기
import heapq
import sys

input = sys.stdin.readline
N = int(input())  # 수업의 개수

class_list = []

for _ in range(N):
    x, y = map(int, input().split())
    class_list.append([x, y])

class_list.sort()
heap = []
heapq.heappush(heap, class_list[0][1])  # 첫 번째 강의 끝나는 시간
# heap 최소 힙 유지 = 0 번째 인덱스는 가장 작은 값

for idx in range(1, N):
    start, end = class_list[idx]
    if start < heap[0]: # 빠른 시작 시간 < 앞에서 가장 빨리 끝나는 값
        heapq.heappush(heap, end) # 새 강의실 추가
    else: # 강의실 유지, 강의 시간 갱신
        heapq.heappop(heap)
        heapq.heappush(heap, end)
print(len(heap))

 

 

그리디 문제 - 2217번 로프

https://www.acmicpc.net/problem/2217

 

2217번: 로프

N(1 ≤ N ≤ 100,000)개의 로프가 있다. 이 로프를 이용하여 이런 저런 물체를 들어올릴 수 있다. 각각의 로프는 그 굵기나 길이가 다르기 때문에 들 수 있는 물체의 중량이 서로 다를 수도 있다. 하

www.acmicpc.net

 

# n = 2  # 로프의 개수
# arr = [10, 15]  # 로프가 버틸 수 있는 최대 중량
n = int(input())
arr = []
for _ in range(n):
    arr.append(int(input()))
arr = sorted(arr, reverse=True)
maxRes = 0

# 내림차순으로 들을 수 있는 로프 개수 * 현재 무게를 계산해서 최대값을 구해준다.
for k in range(n):
    maxRes = max(arr[k]*(k+1), maxRes)
print(maxRes)

 

그리디 문제 - 1026번 보물

https://www.acmicpc.net/problem/1026

 

1026번: 보물

첫째 줄에 N이 주어진다. 둘째 줄에는 A에 있는 N개의 수가 순서대로 주어지고, 셋째 줄에는 B에 있는 수가 순서대로 주어진다. N은 50보다 작거나 같은 자연수이고, A와 B의 각 원소는 100보다 작거

www.acmicpc.net

 

# n = 5  # 정수의 개수
# arrA = [1, 1, 1, 6, 0]  # A 정수 배열
# arrB = [2, 7, 8, 3, 1]  # B 정수 배열

n = int(input())
arrA = list(map(int, input().split()))
arrB = list(map(int, input().split()))

# S = A[0] * B[0] + A[1] * B[1] + ...+ A[N-1] * B[N-1]
# 계산 값을 가장 작게 만들기 위해서는 각 배열을 오름차순, 내림차순 해준다.
arrA.sort()
arrB.sort(reverse=True)
res = 0

for x in range(n):
    res += arrA[x]*arrB[x]

print(res)

 

그리디 문제 - 8980번 택배

https://www.acmicpc.net/problem/8980

 

8980번: 택배

입력의 첫 줄은 마을 수 N과 트럭의 용량 C가 빈칸을 사이에 두고 주어진다. N은 2이상 2,000이하 정수이고, C는 1이상 10,000이하 정수이다. 다음 줄에, 보내는 박스 정보의 개수 M이 주어진다. M은 1이

www.acmicpc.net

 

# 트럭 한 대로 배송할 수 있는 최대 박스 수 출력
N, C = map(int, input().split())  # 마을의 수, 트럭 용량
M = int(input())  # 박스 정보 개수
info = []
res = 0

for _ in range(M):
    # 박스를 보내는 마을, 박스를 받는 마을, 보내는 박스의 개수
    from_box, to_box, num_box = map(int, input().split())
    info.append((from_box, to_box, num_box))

sort_info = sorted(info, key=lambda x: x[1]) # 가장 빨리 받는 순서대로 정렬
remain = [0] * (N+1) # 남은 상자

for item in sort_info:
    start, end, box = item[0], item[1], item[2]
    max_box = box
    for i in range(start, end): # 시작점부터 도착지까지 보낼 수 있는 박스 개수
        max_box = min(max_box, C - remain[i])
    # print(max_box, C-remain[i])
    for j in range(start, end):
        remain[j] += max_box
    res += max_box
print(res)

https://hhiyeon.tistory.com/252

 

[백준] 1541번 잃어버린 괄호

https://www.acmicpc.net/problem/1541 1541번: 잃어버린 괄호 첫째 줄에 식이 주어진다. 식은 ‘0’~‘9’, ‘+’, 그리고 ‘-’만으로 이루어져 있고, 가장 처음과 마지막 문자는 숫자이다. 그리고 연속해서

hhiyeon.tistory.com

 

https://hhiyeon.tistory.com/253

 

[백준] 11501번 주식

https://www.acmicpc.net/problem/11501 11501번: 주식 입력의 첫 줄에는 테스트케이스 수를 나타내는 자연수 T가 주어진다. 각 테스트케이스 별로 첫 줄에는 날의 수를 나타내는 자연수 N(2 ≤ N ≤ 1,000,000)이

hhiyeon.tistory.com

 

https://hhiyeon.tistory.com/254

 

[백준] 2170번 선긋기

https://www.acmicpc.net/problem/2170 2170번: 선 긋기 첫째 줄에 선을 그은 횟수 N (1 ≤ N ≤ 1,000,000)이 주어진다. 다음 N개의 줄에는 선을 그을 때 선택한 두 점의 위치 x, y (-1,000,000,000 ≤ x < y ≤ 1,000,000,000)

hhiyeon.tistory.com

 

https://hhiyeon.tistory.com/255

 

[백준] 1744번 수묶기

https://www.acmicpc.net/problem/1744 1744번: 수 묶기 길이가 N인 수열이 주어졌을 때, 그 수열의 합을 구하려고 한다. 하지만, 그냥 그 수열의 합을 모두 더해서 구하는 것이 아니라, 수열의 두 수를 묶으려

hhiyeon.tistory.com

 

+ Recent posts