알고리즘 유형 : DP(Dynamic Programming)
풀이 참고 없이 스스로 풀었나요? : O
https://www.acmicpc.net/problem/11049
import sys
input = sys.stdin.readline
N = int(input())
matrix = [list(map(int, input().split())) for _ in range(N)]
DP = [[0]*N for _ in range(N)]
# 분할된 그룹의 크기를 1부터 N-1까지 돎
for size in range(1, N):
# 크기 size인 그룹의 모든 경우의 수 돎
for start in range(N - size):
end = start + size
# 어떤 그룹의 최소 곱셈 횟수는 분할한 두 그룹의 최소 곱셈 횟수 + 각 그룹의 곱셈 다 끝나고 남은 행렬끼리의 곱셈 횟수
result = float("inf")
for cut in range(start, end):
result = min(result, DP[start][cut] + DP[cut+1][end] +
matrix[start][0]*matrix[cut][1]*matrix[end][1])
DP[start][end] = result
print(DP[0][-1])
"use strict";
const fs = require("fs");
const input = fs.readFileSync(0).toString().trim().split("\n");
const N = Number(input[0]);
const matrix = [];
for (let i=1; i<N+1; i++){
matrix.push(input[i].split(" ").map(Number));
}
const DP = [];
for (let i=0; i<N; i++){
DP.push([]);
for (let j=0; j<N; j++){
DP[i].push(0);
}
}
for (let size=1; size<N; size++){
for (let start=0; start<N-size; start++){
const end = start + size;
let result = Infinity;
for (let cut=start; cut<end; cut++){
result = Math.min(result, DP[start][cut] + DP[cut+1][end] +
matrix[start][0]*matrix[cut][1]*matrix[end][1]);
}
DP[start][end] = result;
}
}
console.log(DP[0][N-1]);
풀이 요약
가장 바깥 for문
은 분할하고 난 그룹 하나의 크기가 1부터 N-1까지인 경우를 다 도는 것이다. 전체 그룹을 두 개의 그룹으로 계속 분할해가는데, 이 때 길이가 N인 그룹의 최소 곱셈 횟수를 구하려면 길이 1~N-1인 그룹의 최소 곱셈 횟수를 활용한다는 것을 알 수 있다. 즉, 길이가 1인 모든 그룹의 최소 곱셈 횟수, 길이가 2인 모든 그룹의 최소 곱셈 횟수, 이 순서로 길이 N 전체 그룹까지 쭉 구해서 DP 리스트에 메모이제이션해주는 것이다.각 그룹 size에 대해, start는 N-size-1까지만 돈다. N-size일 때부터는, end = N-size+size = N이므로 matrix의 인덱스를 넘어가버리기 때문이다.
여기까지가 두 번째 for문이다.
배운 점, 어려웠던 점