From dd0239338126b89e1bbbe973a6610357117c345c Mon Sep 17 00:00:00 2001 From: SSUM <116950962+ssum21@users.noreply.github.com> Date: Mon, 9 Feb 2026 20:41:42 +0900 Subject: [PATCH] =?UTF-8?q?[Gold=20III]=20Title:=20=ED=96=89=EB=A0=AC=20?= =?UTF-8?q?=EA=B3=B1=EC=85=88=20=EC=88=9C=EC=84=9C,=20Time:=20824=20ms,=20?= =?UTF-8?q?Memory:=20113588=20KB=20-BaekjoonHub?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 백준/Gold/11049. 행렬 곱셈 순서/README.md | 43 +++++++++++++++++++ .../11049. 행렬 곱셈 순서/행렬 곱셈 순서.py | 40 +++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 백준/Gold/11049. 행렬 곱셈 순서/README.md create mode 100644 백준/Gold/11049. 행렬 곱셈 순서/행렬 곱셈 순서.py diff --git a/백준/Gold/11049. 행렬 곱셈 순서/README.md b/백준/Gold/11049. 행렬 곱셈 순서/README.md new file mode 100644 index 0000000..2b3f585 --- /dev/null +++ b/백준/Gold/11049. 행렬 곱셈 순서/README.md @@ -0,0 +1,43 @@ +# [Gold III] 행렬 곱셈 순서 - 11049 + +[문제 링크](https://www.acmicpc.net/problem/11049) + +### 성능 요약 + +메모리: 113588 KB, 시간: 824 ms + +### 분류 + +다이나믹 프로그래밍 + +### 제출 일자 + +2026년 2월 9일 20:40:46 + +### 문제 설명 + +

크기가 N×M인 행렬 A와 M×K인 B를 곱할 때 필요한 곱셈 연산의 수는 총 N×M×K번이다. 행렬 N개를 곱하는데 필요한 곱셈 연산의 수는 행렬을 곱하는 순서에 따라 달라지게 된다.

+ +

예를 들어, A의 크기가 5×3이고, B의 크기가 3×2, C의 크기가 2×6인 경우에 행렬의 곱 ABC를 구하는 경우를 생각해보자.

+ + + +

같은 곱셈이지만, 곱셈을 하는 순서에 따라서 곱셈 연산의 수가 달라진다.

+ +

행렬 N개의 크기가 주어졌을 때, 모든 행렬을 곱하는데 필요한 곱셈 연산 횟수의 최솟값을 구하는 프로그램을 작성하시오. 입력으로 주어진 행렬의 순서를 바꾸면 안 된다.

+ +### 입력 + +

첫째 줄에 행렬의 개수 N(1 ≤ N ≤ 500)이 주어진다.

+ +

둘째 줄부터 N개 줄에는 행렬의 크기 r과 c가 주어진다. (1 ≤ r, c ≤ 500)

+ +

항상 순서대로 곱셈을 할 수 있는 크기만 입력으로 주어진다.

+ +### 출력 + +

첫째 줄에 입력으로 주어진 행렬을 곱하는데 필요한 곱셈 연산의 최솟값을 출력한다. 정답은 231-1 보다 작거나 같은 자연수이다. 또한, 최악의 순서로 연산해도 연산 횟수가 231-1보다 작거나 같다.

+ diff --git a/백준/Gold/11049. 행렬 곱셈 순서/행렬 곱셈 순서.py b/백준/Gold/11049. 행렬 곱셈 순서/행렬 곱셈 순서.py new file mode 100644 index 0000000..91e4413 --- /dev/null +++ b/백준/Gold/11049. 행렬 곱셈 순서/행렬 곱셈 순서.py @@ -0,0 +1,40 @@ +import sys +input = sys.stdin.readline + +N = int(input()) +M = [None] # 1-indexed를 위해 더미 삽입 +for i in range(N): + r, c = map(int, input().split()) + M.append((r, c)) + +# D[s][e]: 행렬 s~e를 곱하는 최소 연산 횟수 (-1이면 아직 미계산) +D = [[-1] * (N + 1) for _ in range(N + 1)] + +def solve(s, e): + # 이미 계산했으면 바로 반환 (메모이제이션) + if D[s][e] != -1: + return D[s][e] + + # Base Case 1: 행렬 1개 → 곱셈 불필요 + if s == e: + return 0 + + # Base Case 2: 행렬 2개 → 바로 곱하기 + if s + 1 == e: + D[s][e] = M[s][0] * M[s][1] * M[e][1] + return D[s][e] + + # Recursive Case: 모든 분할 지점 k 시도 + result = sys.maxsize + for k in range(s, e): + cost = ( + solve(s, k) # 왼쪽 구간 비용 + + solve(k + 1, e) # 오른쪽 구간 비용 + + M[s][0] * M[k][1] * M[e][1] # 두 결과를 합치는 비용 + ) + result = min(result, cost) + + D[s][e] = result + return result + +print(solve(1, N)) \ No newline at end of file