새소식

Algorithm/알고리즘

[Dynamic Programming] 행렬 경로 문제

  • -

문제

* 아래 문제의 recursive property를 제시하라.

 

양 또는 음의 정수 원소들로 구성된 n×n 행렬이 주어지고, 행렬의 좌상단에서 시작하여 우하단까지 이동한다.

 

이동 방법 (제약조건)

- 오른쪽이나 아래쪽으로만 이동할 수 있다.

- 왼쪽, 위쪽, 대각선 이동은 허용하지 않는다.

 

목표

행렬의 좌상단에서 시작하여 우하단까지 이동하되, 방문한 칸에 있는 수들을 더한 값이 최소화되도록 한다.

 

불법 이동 예

 

 

유효한 이동의 예

 

 

문제풀이 방법

 

1. 초기화

- dp[0][0] = matrix[0][0]: 시작점은 그대로 자신의 값으로 초기화

- 첫 행과 첫 열은 이전 값에 현재 칸의 값(matrix의 값)을 더하여 초기화 (for문)

 

2. 점화식 dp[i][j] = matrix[i][j] + min(dp[i-1][j], dp[i][j-1])

- 현재 칸 (i, j)까지의 최소 경로 합은 현재 칸의 값(matrix[i][j])에 아래 두 경우 중 작은 값을 더한다

  • 왼쪽 (i-1, j)에서 오는 경우의 값
  • 위쪽 (i, j-1)에서 오는 경우

3. DP테이블 채우기

- 이중 반복문을 통해 DP 테이블을 채워나간다.

- 이 과정을 통해 좌상단에서 우하단까지의 모든 칸에 대한 최소 경로 합을 계산할 수 있다

 

4. 결과

DP 테이블의 우하단 칸 dp[n-1][n-1]에 저장된 값이 좌상단에서 우하단까지의 최소 경로 합이 된다.

 

 

코드
C++

def min_path_sum(matrix):
    n = len(matrix)
    # 최소 경로 합을 저장할 2차원 DP 테이블 생성
    dp = [[0] * n for _ in range(n)]
    
    # DP 테이블 초기화
    dp[0][0] = matrix[0][0]
    
    # 첫 번째 행 채우기
    for i in range(1, n):
        dp[0][i] = dp[0][i-1] + matrix[0][i]
    
    # 첫 번째 열 채우기
    for j in range(1, n):
        dp[j][0] = dp[j-1][0] + matrix[j][0]
    
    # 나머지 DP 테이블 채우기
    for i in range(1, n):
        for j in range(1, n):
            dp[i][j] = matrix[i][j] + min(dp[i-1][j], dp[i][j-1])
    
    # DP 테이블의 우하단 칸 값이 최소 경로 합
    return dp[n-1][n-1]

# 예제 사용
matrix = [
    [1, 3, 1],
    [1, 5, 1],
    [4, 2, 1]
]
print(min_path_sum(matrix))  # 출력: 7

 

Python

 

def min_path_sum(matrix):
    n = len(matrix)
    # 2차원 배열인 dp테이블 생성
    dp = [[0] * n for _ in range(n)]
    
   #DP테이블 초기화
    dp[0][0] = matrix[0][0]
    
   # 1행은 이전 값으로 채우기
    for i in range(1, n):
        dp[0][i] = dp[0][i-1] + matrix[0][i]
    
    # 1열은 이전 값으로 채우기
    for j in range(1, n):
        dp[j][0] = dp[j-1][0] + matrix[j][0]
    
    # 1행과 1열을 제외한 나머지 칸수 채우기
    for i in range(1, n):
        for j in range(1, n):
            dp[i][j] = matrix[i][j] + min(dp[i-1][j], dp[i][j-1])
    
    #오른쪽 가장 아래의 값 출력
    return dp[n-1][n-1]

#예시
matrix = [
    [1, 3, 1],
    [1, 5, 1],
    [4, 2, 1]
]
print(min_path_sum(matrix))  # Output: 7
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.