동전의 개수 N과 각 동전이 몇 원인지 숫자 N개가 주어진다.

동전들을 조합하여 만들 수 없는 금액 중 최소값을 구하시오

ex)

입력

5

3 2 1 1 9

출력

8

설명

3,2,1,1,9를 잘 조합해서 더하면 1부터 7까지는 만들 수 있는데 8은 만들 수 없다.

 

N은 최대 1000

동전들은 최대 100000원

 

idea

음.. 오름차순으로 정렬해보면 되지 않을까?

오름차순으로 정렬해서 맨 앞에서부터 하나하나 더하면서

1을 만들 수 있는지 2를 만들 수 있는지... 체크해보는건 어떨까

 

라고 생각을 해봤는데 이러면 안된다 ㅋㅋㅋㅋㅋ

위 예시에서 3은 1이랑 2를 조합해야되는데 이런 방법으로 하면 3을 못만듬. 1 -> 1 -> 2 이순서로 더하게돼서 ㅋㅋ ㅠ

 

흠 어떻게할까...

 

정답을 봤는데 이해가 안감

일단 정렬하는건 비슷한데..

 

N = int(input())
data = list(map(int,input().split()))
data.sort()

target = 1
for x in data:
    if target < x:
        break
    target += x

print(target)

 

target을 정해서 1씩 증가시켜가며 확인하는것도 비슷.

근데 이게 왜.. 되는거지?

 

인풋이 3 2 1 1 9면..

첨에 target이 1

1 < 1은 성립하지 않으니

target += 1

target은 2가 된다.

2< 1은 성립하지 않으니

target += 1

target은 3이 된다.

3 < 2가 성립하지 않으니

target += 2

target은 5가 된다

5 < 3은 성립하지 않으니

target += 3

target은 8이 된다

8 < 9가 성립하니까

target = 8

 

어... 왜 되는거지?ㅋㅋㅋㅋㅋㅋㅋㅋㅋ

도저히 이해가 안된다 ㅋㅋㅋㅋㅋ

 

-----------------------------추가-------------------------------

방금 다른 블로그 해설을 보고 조금 이해가 됐다.

[1 9] 의 예시를 보자.

[1]만 있을 때 만들 수 있는 숫자는? 1이 들어가는 경우 안들어가는 경우 다 고려하면 0~1까지의 범위의 숫자를 만들 수 있다.

여기에 9가 갑자기 들어오면?

9+0 ~ 9+1까지의 범위를 추가로 만들 수 있다.

즉 [1,9]로 만들 수 있는 숫자는

0~1, 9~10 해서 0,1,9,10이다.

기존 리스트로 만들 수 있는 숫자범위 0~1과 기존리스트+새숫자로 만들수있는 범위 9~10 사이에 텅빈공간 2~8이 생겼으니 정답은 그 최솟값인 2다.

 

[1 2 3]의 예시를 보자.

첫 번째 숫자만 고려할 때 만들 수 있는 숫자범위는 0~1

두 번째 숫자까지 고려하면 0~1과 2+0~2+1의 합집합. 즉 0~1과 2~3. 두 범위 사이에 빈공간이 없이 정수로서 쭉 이어지므로 [1 2]로는 0~3까지 만들 수 있다.

세 번째 숫자를 고려해보자. 기존 리스트로 만들 수 있는 숫자범위 0~3, 새 숫자+기존리스트범위 = 3+0~3+3인 3~6

0~3과 3~6은 쭉 이어지므로 0~6까지 만들 수 있게 된다.

 

자 그니까 숫자를 하나하나 받아서 더해가면서 새 숫자가 들어왔을 때 만들 수 있는 숫자 범위 중간에 빈공간이 생기나 안생기나 확인하면 되는 것이다. 어떻게 확인할까? 기존 리스트로 만들 수 있는 숫자 최대값 + 1 >= 새 숫자가 무조건 쓰일때의 최소값 이어야 된다.

다시 코드를 잘보자

target = 1
for x in data:
    if target < x:
        break
    target += x

 

target이 바로 [기존 리스트로 만들 수 있는 숫자 최대값 + 1]이다.

처음엔 아무 숫자도 고려하지 않으니까 1이상의 수를 못만들어서 target이 1로 시작한다.

새 숫자 x가 들어왔을 때, 새 숫자가 무조건 쓰인다고 가정하면 그 최소값은 새 숫자 그 자체가 된다.

if target < x 이 부분은

기존 리스트로 만들 수 없는 최소값 < 새 숫자가 쓰일 때의 최소값

을 비교하는 것이다.

예를 들어 [1 1]이 있다고 쳤을 때 기존 리스트로는 최대 2까지 만들 수 있고 만들 수 없는 숫자는 3이다.

새 숫자가 들어옴으로써 이 3을 만들 수 있게되면 반복문을 break할 필요가 없다. 근데 새 숫자가 4면은

기존 범위 0~2에 추가로 4~6까지 만들 수 있게 된다. 즉 3 < 4이므로 중간이 비게된다. 그럼 반복문은 break되고 정답은 3이 된다. 만약 새 숫자가 4가 아니라 3이면 기존범위 0~2에 추가로 3~5까지 만들 수 있게 된다. 그럼 기존범위로 만들 수 없는 최소값 3이 새 숫자가 쓰였을 때의 범위에서 최솟값 3으로 커버가 되므로 다음 target을 6으로 잡고 반복문을 계속하면 되는것이다.

 

아 최대한 설명을 풀어보려고했는데 미래의 내가 이문제를 까먹었을 때 이걸 다시 보고 이해할수있을지 걱정이된다..ㅋㅋㅋㅋㅋ

'코딩 테스트 및 알고리즘 > 이것이 취업을 위한 코딩테스트다' 카테고리의 다른 글

Q23. 국영수  (0) 2022.04.07
Q5. 볼링공 고르기  (0) 2022.04.06
Q03 문자열 뒤집기  (0) 2022.04.05
Q2 곱하기 혹은 더하기  (0) 2022.04.03
Q1. 모험가 길드  (0) 2022.04.03

+ Recent posts