아래와 같이 5와 사칙연산만으로 12를 표현할 수 있습니다.
12 = 5 + 5 + (5 / 5) + (5 / 5)
12 = 55 / 5 + 5 / 5
12 = (55 + 5) / 5
5를 사용한 횟수는 각각 6,5,4 입니다. 그리고 이중 가장 작은 경우는 4입니다.
이처럼 숫자 N과 number가 주어질 때, N과 사칙연산만 사용해서 표현 할 수 있는 방법 중 N 사용횟수의 최솟값을 return 하도록 solution 함수를 작성하세요.
N | number | return |
---|---|---|
5 | 12 | 4 |
2 | 11 | 3 |
예제 #1
문제에 나온 예와 같습니다.
예제 #2
11 = 22 / 2
와 같이 2를 3번만 사용하여 표현할 수 있습니다.
이 문제는 동적 프로그래밍(Dynamic Programming, DP)과 관련된 문제로, 주어진 숫자 N과 일련의 연산을 사용하여 특정 숫자 number를 만들 수 있는 최소 연산 횟수를 구하는 문제이다.
dp
배열 초기화: dp
는 길이 9의 배열로, 각 인덱스에 해당 숫자를 만들 수 있는 모든 조합을 저장하는 집합(Set)이다.
N
을 한 번 사용하여 각 자릿수의 숫자를 생성하고 집합에 추가한다. 예를 들어, N
이 5인 경우 dp[1]
에는 5를, dp[2]
에는 55(5를 2번 연이어 사용한 숫자)를 추가한다.
i
와 j
이중 반복문: 이중 반복문을 사용하여 dp[i]
와 dp[j]
를 조합하여 dp[i]
를 만든다.
i
는 탐색하려는 숫자 길이(1부터 8까지)이다.j
는 현재 숫자 길이보다 작은 숫자 길이(1부터 i-1
까지)이다.a
와 b
를 이용한 연산: dp[j]
에 있는 숫자 a
와 dp[i-j]
에 있는 숫자 b
를 이용하여 가능한 모든 연산을 수행하고 그 결과를 dp[i]
에 추가한다. 가능한 연산은 덧셈, 뺄셈, 곱셈, 나눗셈(정수 나눗셈)이다.
dp[j]
에 있는 숫자 a
와 dp[i - j]
에 있는b
는 현재 사용한 N의 횟수에 따라 나올 수 있는 모든 숫자 조합을 나타낸다.
예를 들어, dp[1]
에는 N을 1번 사용한 경우의 수가 저장되어 있다. 따라서 dp[1]
은 [N]
을 저장한다.
dp[2]
의 경우, N을 2번 사용한 경우의 수를 저장해야 합니다. 여기서 dp[1]
에 있는 숫자 a
와 b
를 조합하여 dp[2]
에 저장한다. 이때 가능한 조합은 다음과 같다:
[N + N, N - N, N * N, N / N]
를 dp[2]
에 추가한다.N을 1번 사용하는 경우
와 N을 2번 사용하는 경우
를 사칙연산하여 저장한다.(1번 3번), (2번 2번), (3번 1번)
사용하는 경우를 사칙연산하여 저장한다.이러한 방식으로, dp[j]
에 있는 숫자 a
와 dp[i - j]
에 있는 숫자 b
는 각각 N을 j
번과 (i - j)
번 사용한 경우의 수를 나타내며, 두 조합을 모두 고려하여 dp[i]
에 저장된다. 이를 반복하면서 모든 가능한 N 사용 횟수에 대한 숫자 조합을 계산한다.
number
가 dp[i]
에 있으면 반환: 각 단계에서 dp[i]
를 만들 때마다 number
가 포함되어 있는지 확인하고, 있다면 i
를 반환한다.
만약 number
를 만들 수 없다면 -1을 반환한다.
이렇게 하면 dp[i]
에는 N
을 i
번 연속 사용하여 만들 수 있는 숫자들이 저장되고, number
가 나타나는 순간 그 때의 i
를 반환하여 최소 연산 횟수를 찾아낸다.
✅ 답안
function solution(N, number) {
let dp = new Array(9).fill(0).map(() => new Set()); // DP 테이블 초기화
for (let i = 1; i < 9; i++) {
// 숫자 N을 i번 반복한 수 생성
const num = Number(N.toString().repeat(i));
dp[i].add(num); // DP 테이블에 추가
}
for (let i = 1; i < 9; i++) {
for (let j = 1; j < i; j++) {
for (const a of dp[j]) {
for (const b of dp[i - j]) {
dp[i].add(a + b);
dp[i].add(a - b);
dp[i].add(a * b);
dp[i].add(Math.floor(a / b));
}
}
}
if (dp[i].has(number)) return i;
}
return -1; // 답을 찾지 못한 경우
}