문제 정보

풀이

N과 사칙연산만을 사용해 number를 만들 때, N의 최소 사용 횟수를 구하는 문제다.

dp를 사용하는 문제로, N을 i번 사용해서 만들 수 있는 수를 단계적으로 구해나간다. dp[i]number가 처음 등장하는 순간의 i가 답이다. (단, 문제 조건에 따라 i > 8인 경우 -1 반환)

또한 N을 i번 사용해서 만들 수 있는 수가 여러 개이고, 같은 수가 여러 경로로 만들어질 수 있으므로, dp[i]에는 HashSet<Integer>을 사용한다.

dp[i]를 구할 때는 두 가지 경우를 고려한다.

  1. Ni번 이어붙인 수
  2. i = j + (i - j)로 분할해 사칙연산
    • N을 i번 사용하는 경우를 ‘j번 사용한 결과’와 ‘i - j번 사용한 결과’의 사칙 연산으로 나타낼 수 있다.
    • 예를 들어 dp[4]를 구할 때,
      • dp[1] & dp[3]
      • dp[2] & dp[2]
      • dp[3] & dp[1]
      • 의 모든 경우의 사칙 연산 결과를 dp[4]에 추가한다.

코드

import java.util.*;
 
class Solution {
    public int solution(int N, int number) {
        if (N == number) return 1;
        
        List<Set<Integer>> dp = new ArrayList<>();
        
        for (int i = 0; i <= 8; i++)
            dp.add(new HashSet<>());
        
        for (int i = 1; i <= 8; i++) {
            int repeat = 0;
            for (int k = 0; k < i; k++)
                repeat = repeat * 10 + N;
            
            dp.get(i).add(repeat);
            
            for (int j = 0; j < i; j++) {
                for (int a : dp.get(j)) {
                    for (int b : dp.get(i - j)) {
                        dp.get(i).add(a + b);
                        dp.get(i).add(a - b);
                        dp.get(i).add(a * b);
                        if (b != 0)
                            dp.get(i).add(a / b);
                    }
                }
            }
            
            if (dp.get(i).contains(number))
                return i;
        }
       
        return -1;
    }
}