코테 노트/백준

백준 6236 용돈 관리 Python 3

화요밍 2022. 1. 20. 14:56
728x90
반응형

초https://www.acmicpc.net/problem/6236

 

6236번: 용돈 관리

현우는 용돈을 효율적으로 활용하기 위해 계획을 짜기로 하였다. 현우는 앞으로 N일 동안 자신이 사용할 금액을 계산하였고, 돈을 펑펑 쓰지 않기 위해 정확히 M번만 통장에서 돈을 빼서 쓰기로

www.acmicpc.net

 

최종 코드

 

GitHub - hwayeon351/BEAKJOON-Algorithms: 백준 알고리즘 소스 코드 모음

백준 알고리즘 소스 코드 모음. Contribute to hwayeon351/BEAKJOON-Algorithms development by creating an account on GitHub.

github.com

import sys
def get_withdrawal(money, M):
    left = max(money)
    right = max(money)*len(money)
    answer = right
    while left <= right:
        mid = (left+right)//2
        wallet = 0
        cnt = 0
        for m in money:
            if m <= wallet:
                wallet -= m
            else:
                if cnt >= M: break
                wallet = mid - m
                cnt += 1
        else:
            answer = min(answer, mid)
            right = mid-1
            continue
        left = mid+1
    return answer

input = sys.stdin.readline
N, M = map(int, input().split())
money = list()
for _ in range(N):
    money.append(int(input()))
print(get_withdrawal(money, M))

풀이 과정

풀이 시간 22분

통장에서 K원을 M번만 인출해서 하루하루 돈을 사용할 수 있도록 하는 최소 금액 K를 구하는 문제이다.

이때, K원보다 적은 돈을 쓴 다음날 남은 금액으로 사용 가능하다면 돈을 새로 인출하지 않는다. 반대로 남은 금액이 다음 날 사용할 금액보다 적은 경우에는 남은 돈은 무시하고 K원을 인출해서 사용하는 것이 문제의 포인트다.

따라서 필요한 최소 금액 K원을 구하는 이분 탐색 알고리즘을 짤 수 있다.

import sys
def get_withdrawal(money, M):
	#인출 금액 범위 초기화 -> 하루에 사용할 금액 중 최대 금액보다 크거나 같고, N*max(money)보다 작거나 같아야 한다
    left = max(money)
    right = max(money)*len(money)
    
    #최대 금액으로 K원 초기화
    answer = right
    
    #이분 탐색
    while left <= right:
    	#K원을 mid로 가정
        mid = (left+right)//2
        #현재 가지고 있는 돈
        wallet = 0
        #인출 횟수
        cnt = 0
        
        for m in money:
        	#현재 가지고 있는 금액이 사용할 금액보다 크거나 같은 경우,
            if m <= wallet:
            	#통장에서 돈을 인출하지 않고 현재 가지고 있는 돈으로 소비한다
                wallet -= m
                
            #돈이 부족한 경우,
            else:
            	#인출 횟수가 초과된 경우, mid 값을 조정해야 한다
                if cnt >= M: break
                #인출 횟수가 초과되지 않은 경우, 인출 후 소비한다
                wallet = mid - m
                cnt += 1
        #mid원 인출 금액으로 모든 소비가 이뤄진 경우,
        else:
        	#answer값 갱신
            answer = min(answer, mid)
            #최소의 K원을 찾기 위해 right 범위를 줄인다
            right = mid-1
            continue
        #mid원 인출 금액으로 모든 소비가 불가능한 경우, mid 값을 늘리기 위해 left 범위를 늘린다
        left = mid+1
    return answer

input = sys.stdin.readline
N, M = map(int, input().split())
money = list()
for _ in range(N):
    money.append(int(input()))
print(get_withdrawal(money, M))

#시간복잡도 = O(log n), 공간복잡도 = O(n)
728x90
반응형

'코테 노트 > 백준' 카테고리의 다른 글

백준 2110 공유기 설치 Python 3  (0) 2022.01.21
백준 1654 랜선 자르기 Python 3  (0) 2022.01.20
백준 2343 기타 레슨 Python3  (0) 2022.01.20
백준 2805 나무 자르기 Python3  (0) 2022.01.20
백준 2512 예산 Python3  (0) 2022.01.20