[DP/백준1932] 정수 삼각형

enoch·2020년 11월 3일
0

알고리즘 문제

목록 보기
1/1

정수 삼각형

문제

위 그림은 크기가 5인 정수 삼각형의 한 모습이다.

맨 위층 7부터 시작해서 아래에 있는 수 중 하나를 선택하여 아래층으로 내려올 때, 이제까지 선택된 수의 합이 최대가 되는 경로를 구하는 프로그램을 작성하라. 아래층에 있는 수는 현재 층에서 선택된 수의 대각선 왼쪽 또는 대각선 오른쪽에 있는 것 중에서만 선택할 수 있다.

삼각형의 크기는 1 이상 500 이하이다. 삼각형을 이루고 있는 각 수는 모두 정수이며, 범위는 0 이상 9999 이하이다

입력

첫째 줄에 삼각형의 크기 n(1 ≤ n ≤ 500)이 주어지고, 둘째 줄부터 n+1번째 줄까지 정수 삼각형이 주어진다.

출력

첫째 줄에 합이 최대가 되는 경로에 있는 수의 합을 출력한다.

풀이과정

동적 계획법 (Dynamic Programming)을 사용하여 해결하는 문제이다.
모든 루트를 탐색하면서 최대값을 찾을 수 있지만, 삼각형의 크기가 커질수록 소요시간이 기하급수적으로 늘어나게된다.

문제를 분석해보면 현재 위치에서 아래 두개의 수 중 하나를 선택하여 합이 큰 쪽을 선택하여야 한다.
다른분의 말을 빌려서 사용해보면

이것은 '선택한 값을 만드는 방법은 왼쪽 위의 값 또는 오른쪽 위의 값 중 큰 값을 고른 뒤 더해 나온 값이란 이야기다.'
작성자 occidere


출처 : 코딩과 디버깅 사이 (작성자 : occidere)

정말 잘 설명되어 있는 사진을 찾아서 가져왔다.
더해진 값들을 계속 계산하지 않고 배열을 만들어서 값을 저장해나가면 된다.

값을 저장할 때 새로운 배열을 생성해도 가능하고, 원래 삼각형의 값이 저장되어있는 배열을 업데이트하면서 사용해도 가능하다.

그러나 아무래도 자원을 적게 활용하기 위해서 기존 삼각형이 저장된 배열을 사용하는것이 좋다고 판단했다.

코드 (python)

H = int(input())
T = []
for i in range(H):
    input_ = input()
    line = list(map(int, input_.split(' ')))
    assert len(line) == i + 1
    T.append(line)

k = 2
for i in range(1, H):
    for j in range(k):
        if j == 0:
            T[i][j] = T[i][j] + T[i - 1][j]
        elif i == j:
            T[i][j] = T[i][j] + T[i - 1][j - 1]
        else:
            T[i][j] = max(T[i - 1][j - 1], T[i - 1][j]) + T[i][j]
    k += 1
print(max(T[H - 1]))
profile
🍣 초밥을 사랑하는 백엔드 개발자 입니다 :)

0개의 댓글