문제 정의
주어진 N개의 행렬을 가질 때, 이 행렬들을 곱하는 과정에서 발생하는 연산의 최솟값을 구하는 문제입니다.
행렬 곱셈의 연산 횟수는 다음과 같은 방식으로 계산됩니다:
두 개의 행렬 A와 B가 있을 때, A의 열(Column) 수와 B의 행(Row) 수가 같아야 곱할 수 있습니다.
계산될 연산 횟수는 다음과 같습니다:
연산 횟수 = A의 행 수 * A의 열 수 * B의 열 수
N개의 행렬을 차례로 곱할 수 있지만,어떤 순서로 곱하느냐에 따라서 총 연산 횟수가 달라집니다.
따라서, 최적의 곱셈 순서를 찾아야 하며, 이로 인해 동적 계획법(Dynamic Programming) 기법을 사용할 것입니다.
입력 형식
첫 번째 줄에 행렬의 개수 N(1 ≤ N ≤ 30)이 주어집니다.
두 번째 줄에는 각 행렬의 크기 정보를 나타내는 N개의 정수 M1, M2, …, MN(1 ≤ Mi ≤ 100) 이 주어집니다.
각각의 정수는 행렬의 행 수와 열 수를 나타냅니다.
출력 형식
행렬을 곱할 때의 최소 연산 횟수를 출력합니다.
예제 입력
3
10 20 30
예제 출력
6000
문제 해결 접근법
이 문제는 동적 계획법을 통해 해결할 수 있습니다.
행렬의 곱셈 순서 결정 문제는 다음과 같은 재귀적 관계를 가집니다.
1. 동적 계획법의 정의
DP 배열 dp[i][j]
를 정의합니다. 이는 i부터 j까지의 행렬을 곱할 때의 최소 연산 횟수를 의미합니다.
따라서, 목표는 dp[0][N-1]
을 계산하는 것입니다.
2. 재귀적 관계
dp[i][j] = min(dp[i][k] + dp[k+1][j] + M[i] * M[k+1] * M[j+1])
(i ≤ k < j)
k를 i와 j 사이의 다른 행렬로 설정할 수 있으며, 이를 통해 모든 가능한 조합을 고려하여 최적의 곱셈 순서를 찾아야 합니다.
C# 코드 구현
이제 전체 알고리즘을 C# 코드로 구현해 보겠습니다.
아래의 코드는 입력을 통해 행렬 크기를 읽고, 동적 계획법을 통해 최소 연산 횟수를 계산합니다.
using System;
class Program
{
static void Main(string[] args)
{
int N = int.Parse(Console.ReadLine());
int[] M = new int[N + 1];
string[] dimensions = Console.ReadLine().Split();
for (int i = 0; i < N; i++)
{
M[i] = int.Parse(dimensions[i]);
if (i != 0) M[i + 1] = int.Parse(dimensions[i]);
}
int[,] dp = new int[N, N];
for (int len = 2; len <= N; len++)
{
for (int i = 0; i <= N - len; i++)
{
int j = i + len - 1;
dp[i, j] = int.MaxValue;
for (int k = i; k < j; k++)
{
int q = dp[i, k] + dp[k + 1, j] + M[i] * M[k + 1] * M[j + 1];
dp[i, j] = Math.Min(dp[i, j], q);
}
}
}
Console.WriteLine(dp[0, N - 1]);
}
}
실행 설명
위의 C# 코드는 먼저 행렬의 개수와 크기를 입력받습니다.
dp[i][j]
배열을 초기화한 후, 두 중첩 루프를 통해 모든 행렬의 조합에 대해 인덱스 i와 j를 설정합니다.
또한 k에 대해 가능한 모든 분할을 고려하여 최소 연산 횟수를 계산합니다.
최종적으로 dp[0][N-1]
이 최소 곱셈 연산을 반환합니다.
시간 복잡도와 공간 복잡도
이 알고리즘의 시간 복잡도는 O(N^3)입니다.
두 개의 중첩 루프와 하나의 내부 루프가 있기 때문에 최악의 경우 O(N^3)의 복잡도를 갖습니다.
공간 복잡도는 O(N^2)입니다. DP 배열을 저장하기 위한 메모리 공간을 필요로 합니다.
결론
행렬 곱 연산 횟수의 최솟값을 구하는 문제는 동적 계획법을 통해 효과적으로 해결할 수 있습니다.
위에서 설명한 알고리즘과 코드를 참조하여 코딩 테스트 문제를 해결하는 데 도움이 되길 바랍니다.
연습을 통해 더 많은 문제를 해결하고, 다양한 알고리즘 기법에 익숙해지길 바랍니다.
참고 자료
– 알고리즘 문제에 대한 더 많은 정보는 구글, 백준, 리트코드와 같은 플랫폼에서 찾아보세요.
– 동적 계획법의 기초와 다양한 패턴에 대해서는 관련 서적을 참고하시기 바랍니다.