[Gold III] Title: 행렬 곱셈 순서, Time: 824 ms, Memory: 113588 KB -BaekjoonHub
This commit is contained in:
43
백준/Gold/11049. 행렬 곱셈 순서/README.md
Normal file
43
백준/Gold/11049. 행렬 곱셈 순서/README.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# [Gold III] 행렬 곱셈 순서 - 11049
|
||||
|
||||
[문제 링크](https://www.acmicpc.net/problem/11049)
|
||||
|
||||
### 성능 요약
|
||||
|
||||
메모리: 113588 KB, 시간: 824 ms
|
||||
|
||||
### 분류
|
||||
|
||||
다이나믹 프로그래밍
|
||||
|
||||
### 제출 일자
|
||||
|
||||
2026년 2월 9일 20:40:46
|
||||
|
||||
### 문제 설명
|
||||
|
||||
<p>크기가 N×M인 행렬 A와 M×K인 B를 곱할 때 필요한 곱셈 연산의 수는 총 N×M×K번이다. 행렬 N개를 곱하는데 필요한 곱셈 연산의 수는 행렬을 곱하는 순서에 따라 달라지게 된다.</p>
|
||||
|
||||
<p>예를 들어, A의 크기가 5×3이고, B의 크기가 3×2, C의 크기가 2×6인 경우에 행렬의 곱 ABC를 구하는 경우를 생각해보자.</p>
|
||||
|
||||
<ul>
|
||||
<li>AB를 먼저 곱하고 C를 곱하는 경우 (AB)C에 필요한 곱셈 연산의 수는 5×3×2 + 5×2×6 = 30 + 60 = 90번이다.</li>
|
||||
<li>BC를 먼저 곱하고 A를 곱하는 경우 A(BC)에 필요한 곱셈 연산의 수는 3×2×6 + 5×3×6 = 36 + 90 = 126번이다.</li>
|
||||
</ul>
|
||||
|
||||
<p>같은 곱셈이지만, 곱셈을 하는 순서에 따라서 곱셈 연산의 수가 달라진다.</p>
|
||||
|
||||
<p>행렬 N개의 크기가 주어졌을 때, 모든 행렬을 곱하는데 필요한 곱셈 연산 횟수의 최솟값을 구하는 프로그램을 작성하시오. 입력으로 주어진 행렬의 순서를 바꾸면 안 된다.</p>
|
||||
|
||||
### 입력
|
||||
|
||||
<p>첫째 줄에 행렬의 개수 N(1 ≤ N ≤ 500)이 주어진다.</p>
|
||||
|
||||
<p>둘째 줄부터 N개 줄에는 행렬의 크기 r과 c가 주어진다. (1 ≤ r, c ≤ 500)</p>
|
||||
|
||||
<p>항상 순서대로 곱셈을 할 수 있는 크기만 입력으로 주어진다.</p>
|
||||
|
||||
### 출력
|
||||
|
||||
<p>첫째 줄에 입력으로 주어진 행렬을 곱하는데 필요한 곱셈 연산의 최솟값을 출력한다. 정답은 2<sup>31</sup>-1 보다 작거나 같은 자연수이다. 또한, 최악의 순서로 연산해도 연산 횟수가 2<sup>31</sup>-1보다 작거나 같다.</p>
|
||||
|
||||
40
백준/Gold/11049. 행렬 곱셈 순서/행렬 곱셈 순서.py
Normal file
40
백준/Gold/11049. 행렬 곱셈 순서/행렬 곱셈 순서.py
Normal file
@@ -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))
|
||||
Reference in New Issue
Block a user