오늘은 사과 상자 포장 문제를 풀었다. 이 문제는 주어진 사과의 점수를 기준으로 상자를 구성하고, 최대 이익을 계산하는 것이다. 각 상자는 정해진 개수의 사과를 포함하며, 상자의 가격은 상자 안의 최저 점수와 상자에 담긴 사과의 개수를 곱한 값으로 결정된다. 이 문제를 해결하기 위해 정렬과 반복문을 사용하여 점수를 기준으로 상자를 구성하고 이익을 계산했다.
점수 내림차순 정렬: 사과 점수를 내림차순으로 정렬하여 최상품부터 포장할 수 있도록 했다. 이렇게 하면 높은 점수부터 그룹을 구성할 수 있으므로 각 상자의 이익을 최대화할 수 있다.
반복문을 이용한 상자 구성: stride(from: 0, to: sortedScores.count, by: m)를 사용해 상자를 구성할 위치를 정하고, m개씩 묶어서 상자를 구성한다.
최저 점수를 기준으로 상자 가격 계산: 각 상자의 최저 점수는 상자의 마지막 인덱스에 위치하게 되므로 i + m - 1번째 사과의 점수와 상자의 크기 m을 곱해 이익을 계산한다.
코드 설명
import Foundation
func solution(_ k: Int, _ m: Int, _ score: [Int]) -> Int {
// 점수 배열을 내림차순으로 정렬하여 높은 점수부터 상자를 구성
let sortedScores = score.sorted(by: >)
var maxProfit = 0
// 상자를 구성하여 이익 계산
for i in stride(from: 0, to: sortedScores.count, by: m) {
// 상자를 완성할 수 있는지 확인
if i + m <= sortedScores.count {
// 현재 상자의 최저 점수는 i+m-1 위치의 점수
let boxPrice = sortedScores[i + m - 1] * m
maxProfit += boxPrice
}
}
return maxProfit
}
점수 내림차순 정렬
score.sorted(by: >)로 점수를 내림차순 정렬하여 높은 점수부터 배열한다. 이렇게 하면 큰 점수의 사과들이 앞에 위치해 상자 구성 시 최대 이익을 쉽게 구할 수 있다.
상자 구성 반복문
stride(from: 0, to: sortedScores.count, by: m) 구문을 사용하여 인덱스를 m씩 증가시키며 상자를 구성할 위치를 설정한다. 이 방식은 매 m번째 위치에 상자가 시작되도록 하여, 상자 단위로 반복문을 구성할 수 있다.
상자 이익 계산
상자에 담긴 사과 중 최저 점수는 sortedScores[i + m - 1]에 위치하며, 상자 크기 m과 곱해 상자 가격을 계산한다.
상자 가격을 maxProfit에 더해 총 이익을 구한다.
이익 반환
모든 상자의 가격을 더한 maxProfit 값을 반환하여 최대 이익을 얻는다.
테스트 결과
정확성 테스트를 모두 통과하여 제한 시간 내에 올바른 결과를 도출했다.
정렬을 이용한 최적화: 내림차순으로 정렬하여 높은 점수를 먼저 상자에 포함시킴으로써, 각 상자에 최저 점수를 쉽게 찾을 수 있었다. 이 방식은 효율적인 계산을 가능하게 해 주었다.
반복문의 활용: stride(from:by:)를 사용해 일정 간격으로 반복을 수행함으로써 m개씩 상자를 구성할 수 있었다. 이로 인해 코드가 간결해지고 가독성이 높아졌다.
상자 구성을 위한 조건 처리: 사과가 m개씩 딱 나누어떨어지지 않는 경우, 남는 사과를 처리하지 않고 상자를 완성하는 조건을 추가해야 했다. 이를 위해 if i + m <= sortedScores.count 조건을 추가하여 상자를 완성할 수 있는지 여부를 확인했다.
이번 문제를 통해 정렬과 반복문을 활용한 그리디 알고리즘의 기본적인 접근 방식을 배울 수 있었다. 정렬을 통해 큰 값부터 처리하고, 반복문을 통해 일정한 단위로 묶어 이익을 최적화하는 방식을 이해하게 되었다.