uva442

C - Matrix Chain Multiplication
Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu
Submit  Status  Practice  UVA 442
Appoint description:  System Crawler  (2016-03-13)

Description

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 order you choose.

For example, let A be a 50*10 matrix, B a 10*20 matrix and C a 20*5 matrix. There are two different 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 needed for a given evaluation strategy.

Input Specification

Input consists of two parts: a list of matrices and a list of expressions.

The first line of the input file contains one integer n (  ), representing the number of matrices in the first part. The next nlines each contain one capital letter, specifying the name of the matrix, 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 } <EOF>
Line       = Expression <CR>
Expression = Matrix | "(" Expression Expression ")"
Matrix     = "A" | "B" | "C" | ... | "X" | "Y" | "Z"

Output Specification

For 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 one line containing the number of elementary multiplications needed to evaluate the expression in the way specified by the parentheses.

Sample Input

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))

Sample Output

0
0
0
error
10000
error
3500
15000
40500
47500

15125

题意:第一行输入n代表矩阵的个数,接着n行,每行第一个为大写字母,表示矩阵的名字。第二个为矩阵的行和列。接着是多组字符串输入。对于每一个表达式如果能进行乘法,则输出总的乘法次数,如果不能进行乘法运算,则输出error。

解法:遇到字母就将字母压入堆栈,遇到‘)’则从堆栈中弹出两个数,进行乘法运算,把运算的结果再压入进去。

总结:对于表达式的运算,堆栈是很常用的。

AC:

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <iostream>
#include<stdio.h>
#include<queue>
#include<string.h>
#include<stack>
#include<map>
using namespace std;
#define ll long long int
const int maxn=5006;
struct matr
{
   int a;
   int b;

};
int main()
{
    //freopen("in.txt","r",stdin);
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        map<char,matr>mp;
        stack<matr>sta;
        int vis;
        matr sa,ea;
        ll ans=0;
        char s[maxn];
        for(int i=0;i<n;i++)
        {
            char c[5];
            int v,e;
            scanf("%s%d%d",c,&v,&e);
            mp[c[0]].a=v;
            mp[c[0]].b=e;
        }
        while(scanf("%s",s)!=EOF)
        {
            ans=0;
            vis=1;
            //cout<<s<<endl;
            for(int i=0;i<strlen(s);i++)
            {
                if(s[i]>='A'&&s[i]<='Z')
                {
                    sta.push(mp[s[i]]);
                }
                else if(s[i]==')')
                {
                  ea=sta.top();sta.pop();
                  sa=sta.top();sta.pop();
                  if(sa.b==ea.a)
                  {
                      ans+=sa.b*sa.a*ea.b;
                      sa.a=sa.a;
                      sa.b=ea.b;
                      sta.push(sa);
                  }
                 else
                 {
                    printf("error\n");
                    vis=0;
                    break;
                 }
                }
            }
            if(vis) printf("%lld\n",ans);
        }
    }

    return 0;
}


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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <iostream>
#include<stdio.h>
#include<queue>
#include<string.h>
#include<stack>
#include<map>
using namespace std;
#define ll long long int
const int maxn=5006;
struct matr
{
   int a;
   int b;

};
int main()
{
    //freopen("in.txt","r",stdin);
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        map<char,matr>mp;
        stack<matr>sta;
        int vis;
        matr sa,ea;
        ll ans=0;
        char s[maxn];
        for(int i=0;i<n;i++)
        {
            char c[5];
            int v,e;
            scanf("%s%d%d",c,&v,&e);
            mp[c[0]].a=v;
            mp[c[0]].b=e;
        }
        while(scanf("%s",s)!=EOF)
        {
            ans=0;
            vis=1;
            //cout<<s<<endl;
            for(int i=0;i<strlen(s);i++)
            {
                if(s[i]>='A'&&s[i]<='Z')
                {
                    sta.push(mp[s[i]]);
                }
                else if(s[i]==')')
                {
                  ea=sta.top();sta.pop();
                  sa=sta.top();sta.pop();
                  if(sa.b==ea.a)
                  {
                      ans+=sa.b*sa.a*ea.b;
                      sa.a=sa.a;
                      sa.b=ea.b;
                      sta.push(sa);
                  }
                 else
                 {
                    printf("error\n");
                    vis=0;
                    break;
                 }
                }
            }
            if(vis) printf("%lld\n",ans);
        }
    }

    return 0;
}

你可能感兴趣的:(uva442)