


행렬 너무 어렵습니다. 정석으로 복습하고 오겠습니다.
import sys
input = sys.stdin.readline
N = int(input())
sizes = [tuple(map(int, input().split())) for _ in range(N)]
memo = [[0] * (N) for _ in range(N)]
N에 행렬의 수를 입력받습니다.sizes에 각 행렬의 크기를 (행의 수, 열의 수) 형태로 입력받습니다.memo를 정의합니다. memo[i][j]에는 sizes[i]부터 sizes[j]까지의 행렬을 곱할 때 필요한 곱셈 연산 횟수의 최솟값을 저장합니다.i, j는 0부터 N - 1까지의 인덱스를 가지며, 행렬 곱의 순서를 유지해야 하므로 항상 i ≤ j입니다. 따라서 memo의 아래쪽 절반은 사용하지 않습니다.i == j인 경우,sizes의 i번째부터 i번째 행렬까지 행렬곱을 구하게 되는데... 당연히 행렬이 하나뿐이므로 곱할 게 없습니다.i == j일 땐 memo[i][j] = 0이 됩니다.
memo[i][j]의 값을 구하는 방법을 생각해 봅시다.memo[0][4]의 값을 구해야겠죠.# 아직 완성된 코드는 아님
for k in range(i, j):
memo[i][k] # i번째 ~ k번째 행렬까지 곱함. 이걸 써먹어야 함
memo[k+1][j] # k+1번째 ~ j번째 행렬까지 곱함. 이걸 써먹어야 함
k = 2일 땐 0 ~ 2번째 를, 3 ~ 4번째 를 각각 구하고, 두 결과를 다시 곱합니다.
memo[i][k]겠죠?)memo[k+1][j]겠죠?)
제발 외웁시다. (행이 X개, 열이 Y개) 크기인 행렬을 (행이 Y개, 열이 Z개)인 행렬과 곱하면, 행렬의 크기는 (행이 X개, 열이 Z개)가 됩니다. 제발~~
i번째~k번째 행렬을 곱한 행렬의 크기는 (i번째 행렬의 행 수, k번째 행렬의 열 수)가 됩니다.k+1번째~j번째 행렬을 곱한 행렬의 크기는(k+1번째 행렬의 행 수, j번째 행렬의 열 수)가 됩니다.k번째 행렬의 열 수와 k+1번째 행렬의 행 수는 동일합니다.(i번째 행렬의 행 수) * (k번째 행렬의 열 수) * (j번째 행렬의 열 수)로 구할 수 있습니다. sizes[i][0] * sizes[k][1] * sizes[j][1]로 계산합니다.# 점화식 코드
temp = float('inf') # 최솟값 갱신을 위한 초기 무한의 값
for k in range(i, j):
cost = memo[i][k] + memo[k + 1][j] + sizes[i][0] * sizes[k][1] * sizes[j][1]
if cost < temp:
temp = cost
memo[i][j] = temp
memo[i][k] + memo[k+1][j] + sizes[i][0] * sizes[k][1] * sizes[j][1]가 됩니다.k에 대해 위 값을 계산한 뒤, 최솟값을 memo[i][j]에 저장합니다.
import sys
input = sys.stdin.readline
N = int(input())
sizes = [tuple(map(int, input().split())) for _ in range(N)]
memo = [[0] * (N) for _ in range(N)]
def find_answer():
for gap in range(1, N):
for i in range(N - gap):
j = i + gap
temp = float('inf')
for k in range(i, j):
cost = memo[i][k] + memo[k + 1][j] + sizes[i][0] * sizes[k][1] * sizes[j][1]
if cost < temp:
temp = cost
if i == 0 and j == (N - 1):
return temp
memo[i][j] = temp
print(find_answer())
j - i가 0, 1, 2, 3, ....인 칸 순서대로 채워집니다.gap = j - i이 작은 값부터 채워 나갑니다.memo[i][j]를 계산하려면, 더 왼쪽 아래에 있는 memo[i][k], memo[k+1][j]가 먼저 채워져 있어야 하기 때문입니다.i == 0 and j == (N - 1)일 때 DP 테이블 채우기를 멈추고 바로 답을 반환하게 설정했습니다. for k in range(i, j)로 최대 개의 k를 검사
선생님 행렬을 곱하면 X 행 Z열 아니가요!