행렬 연쇄 곱셈

시간 제한1초메모리 제한128 MB

요약
행렬의 크기와 완전히 괄호로 묶인 곱셈식이 주어질 때, 기본 곱셈 횟수를 출력하고 크기가 맞지 않으면 error를 출력한다.
난이도

보통10점 중 4점

유형
스택, 재귀, 구현
정답자
아직 제출이 없습니다

문제

A\*B\*C\*D\*EA\*B\*C\*D\*E 와 같이 여러 행렬을 곱하는 식을 계산한다고 하자. 여기서 A, B, C, D, E 는 행렬이다.

행렬 곱셈은 결합법칙을 만족하므로 곱셈을 수행하는 순서는 자유롭게 정할 수 있다. 하지만 어떤 순서로 계산하느냐에 따라 필요한 원소 곱셈(elementary multiplication)의 횟수는 크게 달라진다.

예를 들어 AA 가 50×1050 \times 10 행렬, BB 가 10×2010 \times 20 행렬, CC 가 20×520 \times 5 행렬이라고 하자.

A\*B\*CA\*B\*C 를 계산하는 방법은 (A\*B)\*C(A\*B)\*C 와 A\*(B\*C)A\*(B\*C) 두 가지가 있다.

첫 번째 방법은 원소 곱셈이 15000번 필요하지만, 두 번째 방법은 3500번만 필요하다.

괄호로 지정된 계산 순서에 따라 필요한 원소 곱셈의 횟수를 구하는 프로그램을 작성하여라.

입력

입력은 두 부분, 즉 행렬 목록과 식 목록으로 이루어진다.

첫째 줄에는 행렬의 개수를 나타내는 정수 nn (1≤n≤261 \le n \le 26) 이 주어진다. 이어지는 nn 개의 줄에는 각각 행렬의 이름을 나타내는 대문자 하나와, 그 행렬의 행 수와 열 수를 나타내는 두 정수가 주어진다.

입력의 둘째 부분은 다음 EBNF 문법을 엄격히 따른다.

SecondPart = Line { Line } <EOF>
Line       = Expression <CR>
Expression = Matrix | "(" Expression Expression ")"
Matrix     = "A" | "B" | "C" | ... | "X" | "Y" | "Z"

각 줄은 하나의 식이며, 파일의 끝까지 여러 식이 이어질 수 있다.

출력

입력의 둘째 부분에 있는 각 식에 대해 한 줄씩 출력한다. 곱셈 과정에서 두 행렬의 크기가 맞지 않아 오류가 발생하면 "error" 를 출력한다. 그렇지 않으면 괄호로 지정된 순서대로 식을 계산할 때 필요한 원소 곱셈의 횟수를 출력한다.

예제3

  1. 예제 1

    입력
    9
    A 50 10
    B 10 20
    C 20 5
    D 30 35
    E 35 15
    F 15 5
    G 5 10
    H 10 20
    I 20 25
    A
    B
    C
    (AA)
    (AB)
    (AC)
    (A(BC))
    ((AB)C)
    (((((DE)F)G)H)I)
    (D(E(F(G(HI)))))
    ((D(EF))((GH)I))
    
    예상 출력
    0
    0
    0
    error
    10000
    error
    3500
    15000
    40500
    47500
    15125
    
  2. 예제 2

    입력
    1
    A 2 3
    A
    
    예상 출력
    0
    
  3. 예제 3

    입력
    2
    A 2 3
    B 3 4
    (AB)
    
    예상 출력
    24