행렬 N개가 있을 때 적절히 순서를 바꿔 곱을 할 경우 연산 횟수의 최소를 구하는 문제이다.
예를 들어 행렬 A(a,b), B(b,c), C(c,d)가 있을 때 곱하는 경우는 두 가지가 있을 수 있다.
- (AB)C 일 경우 연산 횟수 a*b*c + a*c*d = a*c*(b+d)
- A(BC) 일 경우 연산 횟수 b*c*d + a*b*d = b*d*(a+c)
행렬 곱을 구할 때, 이전에 구한 값을 재사용 할 가능성이 있기 때문에 dp로 문제를 푸는 방향으로 생각해 봤다.
dp[i][j]: i~j까지 행렬까지의 곱 중 가장 적은 연산 횟수라고 정의한다면,
i<=k<=j인 k에 대해 dp[i][k] + dp[k][j] + i*k*j 중 최소값이 dp[i][j]가 될 것이다.
class Solution {
public int solution(int[][] matrix_sizes) {
int length = matrix_sizes.length;
Matrix matrix[] = new Matrix[length + 1];
for (int i = 1; i <= length; i++) {
matrix[i] = new Matrix(matrix_sizes[i - 1][0], matrix_sizes[i - 1][1]);
}
int dp[][] = new int[length + 1][length + 1];
for (int i = length; i > 0; i--) {
for (int j = i + 1; j <= length; j++) {
dp[i][j] = Integer.MAX_VALUE;
for (int k = i; k < j; k++) {
dp[i][j] = Math.min(dp[i][j],
dp[i][k] + dp[k + 1][j] + (matrix[i].row * matrix[k].col * matrix[j].col));
}
}
}
return dp[1][length];
}
}
class Matrix {
int row, col;
public Matrix(int row, int col) {
this.row = row;
this.col = col;
}
}
'알고리즘 공부 > programmers' 카테고리의 다른 글
Programmers 68647: 짝수 행 세기 (0) | 2021.01.28 |
---|---|
Programmers 1843: 사칙연산 (0) | 2021.01.28 |
Programmers 60062: 외벽 점검 (0) | 2021.01.27 |
Programmers 60061: 기둥과 보 설치 (0) | 2021.01.26 |
Programmers 1831: 4단 고음 (0) | 2021.01.24 |