알고리즘 문제 풀이/이코테

[이코테] CH08 다이나믹 프로그래밍 실전문제 32번 정수 삼각형

파란색 가운 2024. 1. 12. 15:26
 

1932번: 정수 삼각형

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

www.acmicpc.net

        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

 

처음엔 대각선 왼쪽 / 오른쪽 조건을 못 보고

그냥 arr[i]별로 맥스값 뽑아서 더하라는거네,, 진짜 쉬운거 만났다

했지만 ~ 저 대각선 조건을 보고 숙연해졌습니다

문제를 딱 보면 뭔가 어떻게 해야할지는 알겠는데

변수가 헷갈린다거나.. 생각보다 코드로 옮기는게 어려운 것 같아요

그래도 처음에 DP 볼땐 뭔 소린지 하나도 몰랐는데

조금씩 문제를 풀어나가는건 뿌듯한 것 같습니다

import sys
# sys.stdin.readline()
from collections import deque
sys.setrecursionlimit(100000000)
import heapq
import copy
import itertools
from itertools import combinations
from itertools import permutations
INF = 1e9
def findMax(arr):
    index = 0
    d = copy.deepcopy(arr)
    for i in range(len(d)):
        for j in range(len(d[i])):
            d[i][j] = 0
    d[0][0] = arr[0][0]
    if N >=2:
     d[1][0] = d[0][0] + arr[1][0]
     d[1][1] = d[0][0] + arr[1][1]
     for i in range(2,N):
        for j in range(len(arr[i])):
         if 0 < j < len(arr[i]) - 1:
          d[i][j] = max(d[i][j], d[i-1][j] + arr[i][j],d[i-1][j-1] + arr[i][j])
         if j == 0:
           d[i][j] = d[i-1][j] + arr[i][j]
         elif j == len(arr[i])-1:
           d[i][j] = d[i-1][j-1] + arr[i][j]
    print(max(d[N-1]))


N = int(input())
arr = [[]] * (N)
for i in range(N):
    arr[i] = list(map(int,sys.stdin.readline().split()))

findMax(arr)

처음엔 if N>=2 조건을 안 해주니까 런타임에러가 나더라고요

문제를 자세히 보니까 삼각형의 높이가 1일수도 있어서

그럼 d[1][0] = 해주는 부분에서 런타임에러가 나는걸 잡아냈습니다

그래서 N>=2인 경우를 따로 분류해줬어요

만약 열이 0이거나 len(arr[i]) - 1인 경우에는 각 왼쪽 /오른쪽에서 오는 경우밖에 없으니 따로 처리해줬고

그 사이에 있는 거는 원래 d[i][j] 값 , 왼쪽, 오른쪽 값중 가장 합계가 큰것을 맥스값으로 잡았습니다

 

DP 테이블을 1차로 처음엔 풀려했는데 풀수 없어서 2차로 바로 틀어서 풀었더니

다행히도 금방 푼 것 같습니다

더 어려운 문제들도 금방금방 푸는 실력을 위하여 ... ! 더 열심히 해야겠어요