ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • DP 실전문제
    알고리즘 (코딩테스트) 2024. 10. 20. 14:50

     

    1. 프로그래머스 - N으로 표현

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

     

    아이디어)

    dp[i] = N을 i번 사용해서 만들 수 있는 숫자들의 집합

    i번 사용했을때 가능한 숫자들은, i-1번까지 사용한 숫자들과 사칙연산을 통해 계산

    ex)

    - dp[1] = { 5 }  : 5를 한번만 사용

    - dp[2] = N을 2번 이어붙인  수+ 이전연산과의 사칙연산 조합

    { 55, 5+5, 5-5, 5/5, 5*5 } :  55, dp[1]과의 사칙연산조합

    - dp[3]은 dp[1]과 dp[2]의 조합

    { 555, 55+5, 55-5, 55*5, 55/5, 10+5, 10-5, 10*5, 10/5, ..... }

    - dp[4]는 dp[1]과 dp[3]의 조합

    - dp[5]는 dp[1]과 dp[4]의 조합 or dp[2]와 dp[3]의 조합

     

    이를 반복하여 dp[i]에서 number가 발견되는 순간, 최소한 횟수 반환

     

    def solution(N, number):
        dp = [set() for _ in range(9)] # dp[1] ~ dp[8] 사용
        # N을 여러 번 이어붙인 경우는 미리 dp에 넣어준다
        # ex. dp[1] = {5}, dp[2] = {55}, dp[3] = {555}
        for i in range(1, 9):
            dp[i].add( int(str(N)*i) )
    
        # dp[i] : i번 사용한 결과는 dp[j]와 dp[i-j]의 조합
        # ex. dp[5] = dp[1]+dp[4] or dp[2]+dp[3] or dp[3]+dp[2] or dp[4]+dp[1]
        for i in range(1, 9):
            for j in range(1, i):
                for op1 in dp[j]:
                    for op2 in dp[i-j]:
                        dp[i].add(op1+op2)  #덧셈
                        dp[i].add(op1-op2)  #뺄셈
                        dp[i].add(op1*op2)  #곱셈
                        if op2 != 0:
                            dp[i].add(op1//op2) #나눗셈
    
            if number in dp[i]:
                return i
        
    
        return -1 # 8까지 사용했는데도 못찾은 경우는 return되는게 없고, 여기서 -1을 반환한다

     

     

     

    2. 프로그래머스 - 등굣길

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

    # 이 문제는 행,열이 반대로 표기되어 있어 유의해야 함!!!
    # dp는 행열을 반대로 표기해서 평소대로 생각하자
    def solution(m, n, puddles):
        dp = [ [0]*(m+1) for _ in range(n+1) ]
        dp[1][1] = 1
        puddles = [[y,x] for [x,y] in puddles]  # 행/열이 반대로 표기되어 있어
    
        # 위에서 오거나, 왼쪽에서 오거나 둘 중 하나
        for i in range(1,n+1):
            for j in range(1,m+1):
                 if i==1 and j==1: continue
                 if [i, j] in puddles:
                    dp[i][j] = 0
                 else:
                    dp[i][j] = ( dp[i-1][j] + dp[i][j-1] ) % 1000000007
        
        return dp[n][m]

     

     

     

    3. 프로그래머스 - 정수 삼각형

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

     

    2차원 dp로 해결

    dp를 트리 모양대로 초기화 하고, 모양대로 합을 차례로 더해감

    - 트리의 양 끝 요소는 더하는데 문제없으나 가운데 끼인 요소는 더할 수 있는 경우가 2가지 존재

    - 합이 더 큰 경우만 dp에 저장한다

    >> 완성된 dp의 맨 마지막 배열이 삼각형 최종 누적 합이고, 이 중 가장 큰 값이 정답

    def solution(triangle):
        N = len(triangle)
        dp = [[0]*len(row) for row in triangle]
        dp[0][0] = triangle[0][0]
    
        # 삼각형 각 층을 순차적으로 탐색
        for i in range(1, N):
            for j in range(len(triangle[i])):
                if j == 0: #삼각형 맨 왼쪽 (위에서 하나만 더할 수 있음)
                    dp[i][j] = dp[i-1][j] + triangle[i][j]
                elif j == len(triangle[i]) - 1: #삼각형 맨 오른쪽 (위에서 하나만 더할 수 있음)
                    dp[i][j] = dp[i-1][j-1] + triangle[i][j]
                else: # 삼각형 중간 - 위에서 두 값 중 큰 값을 더함
                    dp[i][j] = max( dp[i-1][j-1], dp[i-1][j] ) + triangle[i][j]
                
        return max(dp[-1])

    '알고리즘 (코딩테스트)' 카테고리의 다른 글

    DFS/BFS  (0) 2024.10.24
    이분탐색  (0) 2024.10.22
    완전탐색(Brute Force)  (0) 2024.10.21
    DP (다이나믹 프로그래밍) 기본개념/기본문제  (0) 2024.10.17
    다익스트라와 MST(최소신장트리)  (1) 2024.10.16

    댓글

Designed by Tistory.