문제 설명 #
목표: 주어진 hp를 가장 적은 수의 개미를 사용해 0으로 만드는 것입니다. 사용할 수 있는 개미는 다음과 같습니다:
장군개미: 5 병정개미: 3 일개미: 1
문제 #
- 적군의 체력이 인자로 주어집니다.
체력이 6 주어진다면 대략 아래와 같이 개미들을 출동시킬 수 있습니다.
- 장군개미 하나, 일개미 하나
- 병정개미 둘,
- 일개미 여섯
위 예시들 중 개미의 수가 가정 적은 장군개미 하나, 일개미 하나
를 선택하면 됩니다.
후술 #
접근법 #
이 문제는 주어진 체력에 대해 얼마나 효율이 좋은 개미를 몇마리 투입 할 수 있는가?
에 대한 질문으로 다시 생각해볼 수 있습니다.
주어진 체력이 30인 경우, 30 / 5라는 나눗셈에 의해 장군개미 6마리로 체력을 0으로 만들 수 있습니다. 31인 경우, 31 / 5 = 6이고 남은 체력은 1입니다.
이제 반복되는 패턴이 보이게 됩니다.
주어진 개미들을 배열로 세워두고 [5, 3, 1]
배열에 대해 반복문을 순회하면서 각 개미가 얼만큼 체력을 나눌 수 있는가?를 계산하면 됩니다.
풀이 #
필요한 개미의 수를 누산하는 count 변수를 생성합니다. -> let count = 0;
개미들을 공격력이 높은 순서대로 배열로 만들고 -> [5, 3, 1]
배열을 순회하며 인자로 주어지는 hp에 대해 나눗셈 연산을 진행합니다.
- 배열은 내림차순 정렬이 되어 있어 최소한의 필요 개미를 골라낼 수 있습니다.
- 배열이 주어지고 배열을 정렬해야 하는 경우
O(1)
이 아닌O(log)
의 시간을 가질 것입니다.
인자로 체력 6이 주어질 경우
6 / 5
에 대한 연산이 진행됩니다.
hp에 대해 장군 개미가 몇이 필요한지 알 수 있게됩니다.
count라는 변수에 누산해줍니다.
이제 남은 hp는 1이 되어야합니다. hp의 값을 초기화해줍니다. -> hp = hp % ant;
function solution(hp) {
let count = 0;
const ants = [5, 3, 1];
for (const ant of ants) {
if (!hp) break;
const mountOfAnt = ~~(hp / ant);
count += mountOfAnt;
const restHp = hp % ant;
hp = restHp;
}
return count;
}
solution(23); // 5
후술 #
-
주어지는 인자의 hp 값에 따라 고정길이 3인 배열을 순회하므로 해당 알고리즘의
Big O notation은 O(1)
입니다. -
고정길이의 배열을 순회하면서 매번 세 개미들 중 최적의 선택을 합니다.
- 해당 선택은 이전 선택과 이후 선택을 고려하지 않습니다.
-
예전에 풀었던 동전 문제도 위 문제와 같은 방식입니다.