1. 程式人生 > >Matrix Chain Multiplication

Matrix Chain Multiplication

Suppose you have to evaluate an expression like A*B*C*D*E where A,B,C,D and E are matrices.Since matrix multiplication is associative, the order in which multiplications are performed is arbitrary.However, the number of elementary multiplications needed strongly depends on the evaluation orderyou choose.For example, let A be a 50*10 matrix, B a 10*20 matrix and C a 20*5 matrix. There are twodifferent strategies to compute A*B*C, namely (A*B)*C and A*(B*C).The first one takes 15000 elementary multiplications, but the second one only 3500.Your job is to write a program that determines the number of elementary multiplications neededfor a given evaluation strategy.InputInput consists of two parts: a list of matrices and a list of expressions.The first line of the input file contains one integer n (1 ≤ n ≤ 26), representing the number ofmatrices in the first part. The next n lines each contain one capital letter, specifying the name of thematrix, and two integers, specifying the number of rows and columns of the matrix.The second part of the input file strictly adheres to the following syntax (given in EBNF):SecondPart = Line { Line } Line = Expression Expression = Matrix | "(" Expression Expression ")"Matrix = "A" | "B" | "C" | ... | "X" | "Y" | "Z"OutputFor each expression found in the second part of the input file, print one line containing the word ‘error’if evaluation of the expression leads to an error due to non-matching matrices. Otherwise print oneline containing the number of elementary multiplications needed to evaluate the expression in the wayspecified by the parentheses.Sample Input9A 50 10B 10 20C 20 5D 30 35E 35 15F 15 5G 5 10H 10 20I 20 25ABC(AA)(AB)(AC)(A(BC))((AB)C)(((((DE)F)G)H)I)(D(E(F(G(HI)))))((D(EF))((GH)I))Sample Output000error10000error350015000405004750015125

分析:

此題的思路是讀入時,遇到字母,入棧,遇到')'計算。

此題有幾個tips需要注意:

1)要存陣列的序號(A,B,C……)嗎?顯然是不需要的,只需要入讀字元讓該陣列的資訊存到對應的位置就好了(比如A存到0,B存到1),這也方便計算的時候找到對應的陣列(比如說計算時(AB)只需要找到M[0],與M[1]相乘就行,不用再遍歷陣列找陣列序號為'A','B')

2)入棧時,如的是什麼?當然是把整個矩陣入棧了,這樣方便我們計算,連續出兩次棧,結算得到的新矩陣入棧。

程式碼如下:

#include<iostream>
#include<cstdio>
#include<stack>
#include<cstring>
#include<string>
using namespace std;
struct A{
    int x,y;
}M[27];
stack<A> num;
int n;
int main(){
    char ch[3];
    int k;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%s",&ch);
        k=ch[0]-'A';
        scanf("%d%d",&M[k].x,&M[k].y);
    }
    string s;

    while(cin>>s){
        int ans=0;
        int flag=1,len=s.length();
        if(len==1){printf("0\n");flag=0;continue;}
        for(int i=0;i<len;i++){
            if(s[i]=='(')continue;
            if(isalpha(s[i]))num.push(M[s[i]-'A']);
            if(s[i]==')'){
                A t1=num.top();num.pop();
                A t2=num.top();num.pop();
                if(t2.y!=t1.x){printf("error\n");flag=0;break;}
                ans+=t2.x*t2.y*t1.y;
                A t3;
                t3.x=t2.x; t3.y=t1.y;
                num.push(t3);
            }
        }
        if(flag)printf("%d\n",ans);
    }
}