Algo/개념공부
[백준 1932 정수삼각형][Python] -DP 연습!
뉴비코
2023. 9. 15. 07:28
[ 정의 ]
한 번 해결된 부분 문제의 정답을 메모리에 기록하여, 한 번 계산한 답은 다시 계산하지 않도록 한다.
작은 부분으로 큰 것을 계산 한다고 이해 하면 된다!
다이나믹 프로그래밍은 점화식을 코드로 옮겨서 구현할 수 있다.
[ 방법 ]
1. 탑다운 방식
- 재귀 함수를 이용해 큰 문제 해결을 위해 작은 문제를 호출
2. 보텀업 방식
- 반복문을 통해 작은문제 해결 후 이를 모아 큰 문제를 해결
[ 예시 문제 ]
문제
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
위 그림은 크기가 5인 정수 삼각형의 한 모습이다.
맨 위층 7부터 시작해서 아래에 있는 수 중 하나를 선택하여 아래층으로 내려올 때, 이제까지 선택된 수의 합이 최대가 되는 경로를 구하는 프로그램을 작성하라. 아래층에 있는 수는 현재 층에서 선택된 수의 대각선 왼쪽 또는 대각선 오른쪽에 있는 것 중에서만 선택할 수 있다.
삼각형의 크기는 1 이상 500 이하이다. 삼각형을 이루고 있는 각 수는 모두 정수이며, 범위는 0 이상 9999 이하이다.
입력
첫째 줄에 삼각형의 크기 n(1 ≤ n ≤ 500)이 주어지고, 둘째 줄부터 n+1번째 줄까지 정수 삼각형이 주어진다.
출력
첫째 줄에 합이 최대가 되는 경로에 있는 수의 합을 출력한다.
입력
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
출력
30
코드 풀이
n = int(input())
tr = []
for _ in range(n):
a = list(map(int, input().split()))
tr.append(a)
for i in range(n):
for j in range(i+1):
# 처음 행이면 본인이다.
if i == 0:
tr[i][j] = tr[i][j]
continue
# 첫 열이면 위의 것만 받아온다.
if j == 0:
up = tr[i-1][0]
tr[i][j] += tr[i-1][0]
continue
# 마지막 열이면 왼쪽 것만 받아온다.
if j == i :
left = tr[i-1][j-1]
tr[i][j] += tr[i-1][j-1]
continue
# 두 쪽에서 받아오면 두 개 중 큰것을 받아와서 저장한다.
else:
up_left = tr[i-1][j-1]
up_right = tr[i-1][j]
tr[i][j] += max(up_left, up_right)
result = 0
for j in range(n):
result = max(result, tr[n-1][j])
print(result)
DP의 해결방식대로 두 개의 수 중 큰 것을 선택해 내려오는 방식으로 풀이해줬다.
DP는 그림을 그리면 해결하기에 더 쉽다!
차근차근 익혀서 어려운 DP 문제도 잘 풀어나가봐야지.