반응형
https://www.acmicpc.net/problem/1214
1214번: 쿨한 물건 구매
첫째 줄에 D, P, Q가 주어진다. 모두 109보다 작거나 같은 자연수이다.
www.acmicpc.net
해결 방법 : 브루트포스 + (탐색 범위 축소)
- D, P, Q 에 대해, D 이상이 되는 최소의 P*n(n:자연수)을 기준으로 잡고 범위 [0, n-1]에 대해 브루트포스로 탐색하며 P*i(i in [0, n-1]) + Q*m(m:자연수)가 D 이상인 값을 구하면 된다.
- 다만 다음 사항을 이용하여 시간복잡도를 줄일 필요가 있다. (worst case가 10^9 loop이므로..)
- P를 더 큰 값으로 지정한다. (loop 횟수 축소)
- 현재까지의 최솟값 answer가 또 다시 나오면 answer 자체가 반복되는 것이므로 loop를 종료한다.
- 주의할 점이 있는데, loop를 0 to n-1로 잡으면 예외 케이스가 생긴다. 이유를 생각해보면, 만약 주어진 값이 D, P, Q = (51, 6, 9)인 경우, P*n = 54일 것이고, 첫번째 loop에서 P*0 + Q*m 또한 54가 되며 loop가 종료된다. 하지만 6*4 + 9*3 = 51로 best case가 존재한다.
- 따라서, 0 to n-1 이 아니라 n-1 to 0로 탐색해주면 공배수로 인한 예외 처리를 따로 해주지 않아도 될 것이다.
- 다만 다음 사항을 이용하여 시간복잡도를 줄일 필요가 있다. (worst case가 10^9 loop이므로..)
import sys
input = sys.stdin.readline
def solution(D, P, Q):
if D % P == 0 or D % Q == 0: return D
P, Q = max(P, Q), min(P, Q) # P > Q
mx_P = D // P + 1 # P*n이 D 이상이 되게끔하는 최소 n
answer = P * mx_P # 위의 경우 최소 비용
for i in range(mx_P-1, -1, -1): # n-1 to 0 탐색
div, mod = divmod((D - (i * P)), Q) # P*i를 제외한 비용을 Q로 나눈 몫 & 나머지
if mod == 0: return D
mn_i = (i * P) + ((div + 1) * Q) # i에 대한 최소 비용
if answer == mn_i: break # answer가 반복되는 경우
answer = min(answer, mn_i)
return answer
if __name__ == '__main__':
D, P, Q = map(int, input().split())
result = solution(D, P, Q)
print(result)
반응형
'IT study > 알고리즘 문제 풀이' 카테고리의 다른 글
백준 1135 : 뉴스 전하기 (0) | 2021.07.30 |
---|---|
백준 1306 : 달려라 홍준 (0) | 2021.07.30 |
백준 1298 : 노트북의 주인을 찾아서 (0) | 2021.07.26 |
백준 1854 : K번째 최단경로 찾기 (0) | 2021.07.25 |
백준 1305 : 광고 (0) | 2021.07.24 |