알고리즘 & 자료구조/문제 풀이

[프로그래머스 알고리즘 고득점 Kit][동적계획법(Dynamic Programming))][Java] N으로 표현

수수다 2026. 4. 19. 03:35

https://school.programmers.co.kr/learn/courses/30/lessons/42895

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

 

처음보는 형태의 dp 문제였다.
점화식으로 이전 값을 활용하는 것이 아니라
나올 수 있는 결과들을 다음 결과들을 만드는 데 사용한다.

여기서 출력 조건이 8개보다 크면 -1을 출력을 하라고 했는데
이건 다 풀고 나서야 힌트라는 것을 알게 되었다.
8개까지만 구하고 그 이후는 계산할 필요가 없다는 생각으로

사용갯수가 1개인 것부터 하나씩 나올 수 있는 결과들을 만들어서 넘어가는  식으로 풀 수 있다.
연산의 결과가 중복이 많았기 때문에 Set으로 관리했다.

N을 1개 사용했을 때
{N}

2개 사용했을 때

{NN, N+N, N-N, N*N, N/N}  -> 이건 NN과 1개 사용한 집합의 원소들끼리 연산 한 결과를 저장한 것이다.

3개는
NNN 과 1개 사용한 집합과 2개 사용한 집합끼리 + - / * 연산을 기록해주면된다.

이렇게 나아가다가 그 집합에 가장 먼저 number가 등장한다면 그것이 최소 사용 횟수인 정답이된다.

import java.util.*;

class Solution {
    public int solution(int N, int number) {
        if(N == number) return 1;
        
        List<Set<Integer>> dp = new ArrayList<>();
        //dp의 i번째 집합은 N을 i개 사용해서 만들 수 있는 숫자들을 저장
        //0번째 인덱스는 사용하지 않음.
        dp.add(new HashSet<>());
        
        //N을 count만큼 사용해서 나올 수 있는 숫자들을 차례로 저장할거임
        for(int count = 1; count <= 8; count++){ 
            Set<Integer> current = new HashSet<>();
            
            //N, NN, NNN, ... 
            current.add(makeRepeatedNum(N, count));
            
            //i개 사용 집합과 (count - i) 사용 집합의 원소들을 연산 = count개 사용한 집합
            for(int i=1; i<count; i++) {
                Set<Integer> left = dp.get(i); //i번 사용해서 만든 숫자들
                Set<Integer> right = dp.get(count-i);//count-i 사용해서 만든 숫자들
                 
                for(int l : left) {
                    for(int r : right) {
                        current.add(l + r);
                        current.add(l - r);
                        current.add(l * r);
                        if(r != 0) {
                            current.add(l / r);
                        }
                    }
                }
            }
            if(current.contains(number)) return count;
            
            dp.add(current);
        }
        
        //count 8보다 크면 -1 출력
        return -1;
    }
    public int makeRepeatedNum(int N, int count) {
        int num = 0;
        for(int i=0; i<count; i++) {
            num = num * 10 + N;
        }
        return num;
    }
}