1. 문제 설명
특정한 배열이 있다. 주어진 규칙은 M번을 더하여 가장 큰 숫자를 만드는 것이고, 이 때 같은 인덱스에 해당하는 숫자를 최대 K번 까지만 반복하여 더할 수 있다고 한다.
예를 들어 배열 [ 2, 5, 4, 3, 2 ] 가 주어지고, M = 8, K = 3 이라고 주어지면, 8번을 더해 가장 큰 숫자를 만드는 경우이다. 이 때 최대 3번의 반복만큼 하나의 인덱스 숫자에 대해 덧셈이 허용된다.
즉, 5 + 5 + 5 + 4 + 5 + 5 + 5 + 4 = 38 이 가장 큰 숫자가 된다.
반면, 배열 [ 3, 5, 3, 5, 3 ] 이 주어지고, 같은 K, M이 주어질 때 가장 큰 숫자는 다음과 같다.
( 5 + 5 + 5 ) + ( 5 + 5 + 5 ) + 5 + 5 = 40 이 가장 큰 숫자가 된다.
가장 큰 값에 해당하는 원소가 서로 다른 인덱스에 위치한 경우, 번갈아 가며 사용을 허용한다.
2. 문제 풀이
위에서 설명한 예제 그대로 코드에 옮겨보자.
중요한 아이디어는
- 가장 큰 값의 원소를 무조건 K번 반복하게 하는 것, 그리고 두 번째로 큰 원소를 1번 더하는 것
- 위 로직을 M == 0이 될 때 까지 반복한다
M만큼 반복문을 설정하고, 위 아이디어를 해당 반복문에 삽입하면 된다.
코드로 구현하면 다음과 같다.
입력값을 얻고, 입력된 배열을 먼저 정렬 하고 나서 가장 큰 값의 원소와 두 번째로 큰 값의 원소를 추출한다.
결과값을 선언한 후, 로직에 따라 구현된 부분에 따라 값을 더한 후 출력한다.
이걸 더 응용하여 생각하면, K번 반복되어 더해지는 가장 큰 수와 한 번 씩 더해지는 두 번째로 큰 수를 한 묶음으로 생각할 수 있다.
이 묶음의 길이는 K + 1로 생각할 수 있고, M을 이 길이로 나눈 몫이 바로 수열이 반복되는 횟수가 된다.
그 수열이 반복되는 횟수에서 다시 K를 곱한 값이 바로 가장 큰 수가 더해진 횟수가 된다.
하지만 M이 K + 1로 나눠지지 않을 경우도 존재하여, 그 때 나머지만큼 가장 큰 수가 추가적으로 더해진다.
이를 최종 계산하면,
- 가장 큰 수가 더해진 횟수 = int(M / (K + 1)) * K + M % ( K + 1 )
- 두 번째로 큰 수가 더해지는 횟수 = M - ( 가장 큰 수가 더해진 횟수 )
- 최종 결과 = 가장 큰 수 더해진 횟수 * 가장 큰 수 + 두 번째로 큰 수가 더해진 횟수 * 두 번쨰로 큰 수
이를 코드로 구현하면,
3. 느낀 점
Python에서 입력값을 map으로 한번에 입력받을 수 있음을 배웠다.
마찬가지로 배열 역시 해당 코드를 list에 넣어서 선언할 수 있음을 배울 수 있었다.
Greedy는 최소, 최대, 가장 ~한 이라는 조건을 잘 살피고, 해당 문제가 Greedy한 해결법이 있는지 고민해보아야 한다.
'Algorithm > Greedy' 카테고리의 다른 글
1이 될 때 까지 ( 2018 알고리즘 대회 ) (0) | 2021.03.03 |
---|---|
숫자 카드 게임 ( 2019 국가 교육기관 코딩 테스트 ) (0) | 2021.03.02 |