Lv3. 정수 삼각형 ( Python )
# 문제 설명
위와 같은 삼각형의 꼭대기에서 바닥까지 이어지는 경로 중, 거쳐간 숫자의 합이 가장 큰 경우를 찾아보려고 합니다. 아래 칸으로 이동할 때는 대각선 방향으로 한 칸 오른쪽 또는 왼쪽으로만 이동 가능합니다. 예를 들어 3에서는 그 아래칸의 8 또는 1로만 이동이 가능합니다.
삼각형의 정보가 담긴 배열 triangle이 매개변수로 주어질 때, 거쳐간 숫자의 최댓값을 return 하도록 solution 함수를 완성하세요.
# 제한 사항
- 삼각형의 높이는 1 이상 500 이하입니다.
- 삼각형을 이루고 있는 숫자는 0 이상 9,999 이하의 정수입니다.
# 입출력 예
triangle | result |
---|---|
[[7], [3, 8], [8, 1, 0], [2, 7, 4, 4], [4, 5, 2, 6, 5]] | 30 |
문제 해결 시 고려사항
- Dynamic Programming, 점화식을 이용한 문제해결
본 문제는 DP를 이용한 문제 해결이 가능하다. 문제 해결에서 유의해야 할 점은 이 전 상태를 이용하여 새로운 상태를 만들어나가는 것인데, 본 문제에서 사용해야하는 이전 상태에 해당하는 자료는 현재 줄(행)의 윗 줄(행)의 원소들이다.
우선 dp의 첫 줄에 대해서는 dp 작업의 필요 없으니 주어지는 triangle의 첫 줄의 값을 할당한다.
dp = [] dp.append(triangle[0])
이 후에는, 두 번째 줄부터 윗 줄의 정보를 사용하여 dp를 채워나간다.
윗 줄의 원소를 이용할 때 고려해야 할 조건은 다음과 같은 3가지가 존재한다.
- 현재 줄의 가장 좌측 dp를 만드는 경우
- 현재 줄의 가장 우측 dp를 만드는 경우
- 이 외, 즉 사이에 위치한 dp를 만드는 경우
위의 고려사항들을 고려하여 아래와 같이 반복문을 작성한다.
# 두 번재 줄부터 위의 숫자 중 해당 위치로 올 수 있는 수와의 합 중 최대치를 dp에 저장 for i in range(1, len(triangle)): tmp = [] for j in range(len(triangle[i])): # 해당 줄의 가장 좌측 원소일 경우 => 같은 열의 윗줄의 원소와의 합 if j==0: tmp.append(triangle[i][j] + dp[i-1][0]) # 해당 줄의 가장 우측 원소일 경우 => 현재 열 - 1의 윗줄의 원소와의 합 elif j==len(triangle[i])-1: tmp.append(triangle[i][j] + dp[i-1][len(triangle[i-1])-1]) # 이 외의 경우 => 윗 줄의 -1 열과 동일 열 중 큰 수와의 합 else: tmp.append(triangle[i][j] + max(dp[i-1][j-1], dp[i-1][j])) # 해당 줄(행)에 대한 dp 추가 dp.append(tmp)
위와 같은 작업이 모두 끝나면 전체에 대한 dp 작성이 완료되는데, 이 문제에서는 거쳐간 숫자의 최댓값을 return하라고 명시되어 있으니 dp의 가장 아랫줄 중 최댓값을 return 한다.
# 마지막 행의 최대값 반환 return max(dp[len(triangle)-1])
N이 3인 경우
위와 같은 정보를 최종 정리하여 아래와 같이 작성하였다.
tile = [0,1,2] for i in range(3,n+1): tile.append(tile[i-2] % 1000000007 + tile[i-1] % 1000000007) return tile[n] % 1000000007
전체 코드
def solution(triangle):
dp = []
dp.append(triangle[0])
# 두 번재 줄부터 위의 숫자 중 해당 위치로 올 수 있는 수와의 합 중 최대치를 dp에 저장
for i in range(1, len(triangle)):
tmp = []
for j in range(len(triangle[i])):
# 해당 줄의 가장 좌측 원소일 경우 => 같은 열의 윗줄의 원소와의 합
if j==0:
tmp.append(triangle[i][j] + dp[i-1][0])
# 해당 줄의 가장 우측 원소일 경우 => 현재 열 - 1의 윗줄의 원소와의 합
elif j==len(triangle[i])-1:
tmp.append(triangle[i][j] + dp[i-1][len(triangle[i-1])-1])
# 이 외의 경우 => 윗 줄의 -1 열과 동일 열 중 큰 수와의 합
else:
tmp.append(triangle[i][j] + max(dp[i-1][j-1], dp[i-1][j]))
# 해당 줄(행)에 대한 dp 추가
dp.append(tmp)
# 마지막 행의 최대값 반환
return max(dp[len(triangle)-1])