백준 11049번 행렬 곱셈 순서

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <string>
#include<cstring>
#include<queue>
#include <vector>
#include <algorithm>
#include<cmath>
using namespace std;
 
int n, diagonal;
//행렬A_i~부터 A_j까지 곱셈 연산 최소값 저장 M[i][j];
int M[501][501];
int d[501];
int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> d[i] >> d[i + 1];
    }
 
    for (diagonal = 1; diagonal <= n - 1; diagonal++) {
        for (int i = 1; i <= n - diagonal; i++) {
            int j = i + diagonal;
            for (int k = i; k <= j - 1; k++) {                
                if (M[i][j]==0||(M[i][j] > M[i][k] + M[k+1][j] + d[i - 1* d[k] * d[j]) ) {
                    M[i][j] = M[i][k] + M[k+1][j] + d[i - 1* d[k] * d[j];
                }
            }
        }
    }
    cout << M[1][n];
 
    return 0;
}
cs

출처:https://www.acmicpc.net/problem/11049


연쇄 행렬 곱셈 알고리즘을 이용해서 풀 수 있는 문제였습니다.

diagonal1 diagonal2 diagonal3 diagonal4 diagonal5
0 30 64 132 226 348
0 24 72 156 268
0 72 198 366
0 168 392
0 336
0

위의 그림은 M[i][j]의 완성된 값을 의미하며

diagonal은 대각선을 의미하고 

Case1:diagonal1

M[1][2]==30,M[2][3]==24......

Case2:diagonal2

M[1][3]==64,M[2][4]==72..... 

이런 식으로 이해하면 됩니다. 

연쇄행렬곱셈의 점화식입니다.


이 방법은 시간 복잡도 O(n^3)이지만 O(n^2), O(nlgn) 방법도 있다고 하니 찾아봐야겠습니다. 

위 사진의 예제는 백준의 예제와 다른 입력을 사용해봤습니다.



'알고리즘 > BAEKJOON' 카테고리의 다른 글

백준 16398번 행성연결  (0) 2019.03.27
백준 7569번 토마토  (0) 2019.03.27
백준 13700번 완전 범죄  (0) 2019.03.26
백준 11780번 플로이드2  (0) 2019.03.26
백준 11404번 플로이드  (0) 2019.03.26

+ Recent posts