본문 바로가기

알고리즘

[백준] 1932번: 정수 삼각형

반응형

백준 1932번: 정수 삼각형

https://www.acmicpc.net/problem/1932

시간 제한 메모리 제한 제출 정답 맞은 사람 정답 비율
2 초 128 MB 34786 20338 15072 58.708%

문제

        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번째 줄까지 정수 삼각형이 주어진다.

출력

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

예제 입력 1

5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5

예제 출력 1

30

출처

Olympiad > International Olympiad in Informatics > IOI 1994 1번

DP = 점화식

DP는 큰 문제를 작은 문제로 나누어 푸는 문제입니다. Divide and Conquer와는 달리 작은 문제의 답이 변경되지 않고, 반복됩니다. 즉, DP 문제를 일반화 하는 점화식을 찾으면 어렵지 않게 해결할 수 있습니다.

정수 삼각형의 점화식

정수 삼각형의 한 가운데를 기준으로 생각해보면, 마지막 줄 2에 도달하기 위한 경로는 두 가지입니다. 7에서부터 오는 경로와 4에서부터 오는 경로. 문제 정의에 따라, 둘 중 더 큰 쪽을 택해야 합니다. 이를 일반화 한 점화식은 다음과 같습니다.

n\_{i,j} = n\_{i-1,j-1} + n\_{i-1,j}

주의해야 할 점은, 이러한 점화식에는 예외가 존재할 수 있다는 것입니다. 위 문제에서 각 줄의 가장 왼쪽, 가장 오른쪽에 도달하는 경로는 한 가지 밖에 없으며, 점화식을 그대로 적용할 수 없습니다. 이 경우를 예외 처리한 코드는 아래와 같습니다.

n = int(input()); tri = []
for _ in range(n):
    tri.append([int(x) for x in input().split(" ")])

for i in range(1, n):
    for j in range(i+1):
        if j == i:
            tri[i][j] += tri[i-1][j-1]
        elif j == 0:
            tri[i][j] += tri[i-1][j]
        else:
            tri[i][j] += max(tri[i-1][j-1], tri[i-1][j])

print(max(tri[-1]))
반응형