가지고 있는 동전 중에서 큰 단위가 항상 작은 단위의 배수이므로 작은 단위의 동전들을 종합해 다른 해가 나올 수 없기 때문이다. 대부분의 그리디 알고리즘 문제에서는 이처럼 문제 풀이를 위한 최소한의 아이디어를 떠올리고 이것이 정당한지 검토할 수 있어야 답을 도출 할 수 있다.
실전 문제 1 - 큰 수의 법칙
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
# 큰 수의 법칙 n, m, k = map(int, input().split()) data = list(map(int, input().split()))
data.sort()
a, b = data[n - 1], data[n - 2]
result = 0
for i inrange(1, m + 1): if i % k == 0: result += b else: result += a
print(result)
시간 초과 문제를 해결하기 위한 방법
반복되는 수열에 대해서 파악
큰 수가 더해지는 회수를 미리 계산
$int(M/(K+1))*K + M\ % \ (K + 1)$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
# 큰 수의 법칙 최적화 n, m, k = map(int, input().split()) data = list(map(int, input().split()))
data.sort()
a, b = data[n - 1], data[n - 2]
count = int(m / (k + 1)) * k count += m % (k + 1)
result = 0 result += (count) * first result += (m - count) * second
print(result)
실전문제 2 - 숫자 카드 게임
1 2 3 4 5 6 7 8 9 10
n, m = map(int, input().split())
max_value = 0
for i inrange(n): data = list(map(int, input().split())) data.sort() max_value = max(max_value, data[0])
print(max_value)
각 행마다 가장 작은 수를 찾은 뒤에 그 수 중에서 가장 큰 수
실전문제 3 - 1이 될때 까지
1 2 3 4 5 6 7 8 9 10 11 12
n, k = map(int, input().split())
count = 0
while n != 1: if n % k == 0: n //= k else: n -= 1 count += 1
print(count)
최대한 많이 나누는 것이 유리하다 효율적으로 빼기위한 방법을 고려해야한다. $target = (n // k) * k$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
# 효율적인 방법으로 n, k = map(int, input().split())
count = 0
while n != 1: if n % k == 0: n //= k count += 1 elif n >= k: target = (n // k) * k count += (n - target) n = target else: break