본문으로 바로가기
Archive for AI Study
Algorithm

[Programmers/Python] Level_3: N으로 표현

문제: N으로 표현(DP)

문제: N으로 표현(DP)

문제 설명

아래와 같이 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은 1 이상 9 이하입니다.
number는 1 이상 32,000 이하입니다.
수식에는 괄호와 사칙연산만 가능하며 나누기 연산에서 나머지는 무시합니다.
최솟값이 8보다 크면 -1을 return 합니다.

def solution(N, number):
    '''
    1: 5/5 ->2개
    2: 5/5 + 5/5 -> 4개
    
    3: 5-5/5 - 5/5 -> 5개
    4: 5 - 5/5 -> 3개
    5: 5 -> 1개
    6: 5 + 5/5 -> 3개
    7: 5 + 5/5 + 5/5 -> 5개
    
    8: 5 + 5 - 5/5 - 5/5 -> 6개
    9: 5+5 -5/5 -> 4개
    10: 5+5 -> 5개
    11: 55/5 -> 3개
    12: 55/5 + 5/5 -> 5개
    
    13: 5+5+5 - 5/5 - 5/5 -> 7게
    14: 5+5+5 - 5/5 -> 5개
    15: 5+5+5 -> 3개
 
    N을 이용해서 number만드는 최소횟수 -> 일반화가능
    
    dp[number] = number를 만드는 데 필요한 N의 최소 개수
    -> dp[number]를 리턴하기 -> 이거 나열해봤자 점화식에서 규칙이 안보임..
    
    dp[1] = 5(기본)
    dp[2] = 55(기본), 5+5,5-5,5//5, 5*5 -> dp[i-1] (사칙연산) dp[i-1]
    dp[3] = 555(기본), ... -> dp[1] (사칙연산) dp[2]
    -> dp[n] = dp[n-1] 사칙연산 dp[n-2]..?
    사칙연산 하면 겹치는 경우의 수도 있으니깐 set으로 관리하기
    N을 사용하는 횟수를 key로, N을 key번 사용해서 만들 수 있는 집합을 key로 갖는 dict만들기
    
    1. N최대사용횟수는 8이니깐 8개의 set을 value로 갖는 dict dp만들기
    2. dp의 기본값 추가 -> N, nn, nnn....
    3. 점화식관계를 이용해서 for문 돌면서 이전 dp로 현재 dp의 set에 사칙연산 경우의수 추가하기
    4. dp dict완성하고 난 다음에는 dp dict 1부터 8까지 돌면서 number가 set안에 있나 체크
        있으면 return i, 없으면 return -1
    '''
    #dp[i]는 N을 i번 써서 만들 수 있는 숫자들을 set으로 저장 (i는 최대 8)
    dp = {i:set() for i in range(1,9)}
    
    # N을 1번써서 만들 수 있는 숫자는 N
    dp[1].add(N)
    for i in range(2,9):
        # N, NN, NNN 꼴의 기본꼴 추가
        dp[i].add(int(str(N)*i))
        for j in range(1,i):
            
            # j+ i-j = i인 모든 경우의수에 대해 사칙연산
            for num1 in dp[j]:
                for num2 in dp[i-j]:
                    dp[i].add(num1+num2)
                    dp[i].add(num1-num2)
                    if num2 != 0:
                        dp[i].add(num1//num2)
                    dp[i].add(num1*num2)
    
    for i in range(1,9):
        if number in dp[i]:
            return i
    return -1                     

배울점

  1. dp문제를 풀때는 점화식을 찾아야됨 -> 어디서 점화식이 나올지 여러방면으로 고민해봐야됨
    • 이 문제에서는 number가 아니라 N을 사용하는 횟수 i에서 점화식을 찾을 수 있었음.
  2. set에 값을 추가할때는 set.add()꼴로 add()함수를 써야됨
PythonProgrammersxLebel3DP

Continue exploring

더 읽어보기

모든 글