Matrix Chain Multiplication(表达式求值用栈操作)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1082

Matrix Chain Multiplication

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1382    Accepted Submission(s): 905

Problem Description

Matrix multiplication problem is a typical example of dynamical programming.

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

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 (1 <= n <= 26), representing the number of matrices in the first part. The next n lines 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

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

Source

University of Ulm Local Contest 1996

题意:这里介绍一种写结构体重构造函数比较神奇的写法;详见刘汝佳大神的代码

题解:一道水题,注意表达式求值的题应当马上想到用栈来实现

自己的ac代码

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<string>
 4 #include<algorithm>
 5 #include<map>
 6 #include<iostream>
 7 using namespace std;
 8 #define N 30
 9 #define M 50000
10 struct Mnode{
11     int m;
12     int n;
13 }mm[N];
14 Mnode stk[M];
15
16 int main()
17 {
18     int t;
19     while(~scanf("%d",&t))
20     {
21         map<char,int> mp;
22         for(int i = 0; i <  t; i++)
23         {
24             char ch;
25             int m, n;
26             getchar();
27             scanf("%c %d %d",&ch,&m,&n);
28             mp[ch] = i;
29             mm[i].m = m;
30             mm[i].n = n;
31         }
32         char ml[1000];
33         while(~scanf("%s",ml))
34         {
35         int top = 0;
36         int ans = 0;
37         bool flag = 1;
38         for(int i = 0; i < strlen(ml); i++)
39         {
40             if(ml[i]<=‘Z‘&&ml[i]>=‘A‘){
41                 Mnode tm;
42                 tm.m = mm[mp[ml[i]]].m;
43                 tm.n = mm[mp[ml[i]]].n;
44                 stk[top++] = tm;
45             }
46             else if(ml[i]==‘)‘){
47                 Mnode tm1,tm2,tm3;
48                 tm2 = stk[--top];
49                 tm1 = stk[--top];
50                 if(tm1.n!=tm2.m){ puts("error");    flag = 0; break;    }
51                 tm3.m = tm1.m;
52                 tm3.n = tm2.n;
53                 ans+=tm1.m*tm1.n*tm2.n;
54                 stk[top++] = tm3;
55             }
56         }
57         if(flag) printf("%d\n",ans);
58         }
59     }
60     return 0;
61 }

刘汝佳大神的代码,注意其中的构造函数的写法,表示如果没有参数的时候自动默认两个参数值都是0

 1 #include<cstdio>
 2 #include<stack>
 3 #include<iostream>
 4 #include<string>
 5 using namespace std;
 6 struct Matrix{
 7     int a, b;
 8     Matrix(int a = 0, int b = 0):a(a),b(b){}
 9 }m[26];
10 stack<Matrix> s;
11
12 int main()
13 {
14     int n;
15     cin>>n;
16     for(int i = 0; i < n; i++){
17         string name;
18         cin>>name;
19         int k = name[0]-‘A‘;
20         cin>>m[k].a>>m[k].b;
21     }
22     string expr;
23     while(cin>>expr){
24         int len = expr.length();
25         bool error = false;
26         int ans = 0;
27         for(int i = 0; i < len; i++){
28             if(isalpha(expr[i])) s.push(m[expr[i]-‘A‘]);
29             else if(expr[i]==‘)‘){
30                 Matrix m2 = s.top();s.pop();
31                 Matrix m1 = s.top();s.pop();
32                 if(m1.b!=m2.a){error = true; break;}
33                 ans += m1.a*m1.b*m2.b;
34                 s.push(Matrix(m1.a,m2.b));
35             }
36         }
37         if(error) printf("error\n"); else printf("%d\n",ans);
38     }
39     return 0;
40 }
时间: 2024-12-29 12:06:34

Matrix Chain Multiplication(表达式求值用栈操作)的相关文章

NYOJ35 表达式求值 【栈】

表达式求值 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 ACM队的mdd想做一个计算器,但是,他要做的不仅仅是一计算一个A+B的计算器,他想实现随便输入一个表达式都能求出它的值的计算器,现在请你帮助他来实现这个计算器吧. 比如输入:"1+2/4=",程序就输出1.50(结果保留两位小数) 输入 第一行输入一个整数n,共有n组测试数据(n<10). 每组测试数据只有一行,是一个长度不超过1000的字符串,表示这个运算式,每个运算式都是以"

UVa 442 Matrix Chain Multiplication(矩阵链乘,模拟栈)

题意  计算给定矩阵链乘表达式需要计算的次数  当前一个矩阵的列数等于后一个矩阵的行数时  他们才可以相乘  不合法输出error 输入是严格合法的  即使只有两个相乘也会用括号括起来  而且括号里最多有两个 那么就很简单了 遇到字母直接入栈  遇到反括号计算后入栈  然后就得到结果了 #include<cstdio> #include<cctype> #include<cstring> using namespace std; const int N = 1000;

表达式求值_栈

问题 C: 表达式求值 时间限制: 3 Sec  内存限制: 128 MB提交: 1  解决: 1[提交][状态][讨论版] 题目描述 ACM队的mdd想做一个计算器,但是,他要做的不仅仅是一计算一个A+B的计算器,他想实现随便输入一个表达式都能求出它的值的计算器,现在请你帮助他来实现这个计算器吧.比如输入:“1+2/4=”,程序就输出1.50(结果保留两位小数) 输入 第一行输入一个整数n,共有n组测试数据(n<10).每组测试数据只有一行,是一个长度不超过1000的字符串,表示这个运算式,每

表达式求值 (栈应用)

简单计算器 Description 计算一个算术表达式的值.(式子中每个数都是一位数,且除法运算时整除,即3/2=1.输入数据保证每个表达式合法.) Input 有多组测试样例.一个算术表达式占一行. Output 输出表达式的值. Sample Input 1+1 2*3 Sample Output 2 6 分析:就是一个含有加减乘除的表达式,并且不含有括号,计算其值.明明是很简单的表达式求值,愣是让我水了几个小时,也是醉了...看来真是老了 表达式求值:1.先按照计算法则,给出各运算符的优先

【NYOJ-35】表达式求值——简单栈练习

表达式求值 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 Dr.Kong设计的机器人卡多掌握了加减法运算以后,最近又学会了一些简单的函数求值,比如,它知道函数min(20,23)的值是20 ,add(10,98) 的值是108等等.经过训练,Dr.Kong设计的机器人卡多甚至会计算一种嵌套的更复杂的表达式. 假设表达式可以简单定义为: 1. 一个正的十进制数 x 是一个表达式. 2. 如果 x 和 y 是 表达式,则 函数min(x,y )也是表达式,其值为x,y

河南省第四届acm省赛 表达式求值(栈的应用)

表达式求值 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 Dr.Kong设计的机器人卡多掌握了加减法运算以后,最近又学会了一些简单的函数求值,比如,它知道函数min(20,23)的值是20 ,add(10,98) 的值是108等等.经过训练,Dr.Kong设计的机器人卡多甚至会计算一种嵌套的更复杂的表达式. 假设表达式可以简单定义为: 1. 一个正的十进制数 x 是一个表达式. 2. 如果 x 和 y 是 表达式,则 函数min(x,y )也是表达式,其值为x,y

leetcode 150. 逆波兰表达式求值(栈)

根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 说明: 整数除法只保留整数部分. 给定逆波兰表达式总是有效的.换句话说,表达式总会得出有效数值且不存在除数为 0 的情况. 示例 1: 输入: ["2", "1", "+", "3", "*"] 输出: 9 解释: ((2 + 1) * 3) = 9 示例 2: 输入: [&qu

4132:四则运算表达式求值(栈)

总时间限制: 1000ms 内存限制:  65536kB 描述 求一个可以带括号的小学算术四则运算表达式的值 输入 一行,一个四则运算表达式.'*'表示乘法,'/'表示除法 输出 一行,该表达式的值,保留小数点后面两位 样例输入 输入样例1: 3.4 输入样例2: 7+8.3 输入样例3: 3+4.5*(7+2)*(3)*((3+4)*(2+3.5)/(4+5))-34*(7-(2+3)) 样例输出 输出样例1: 3.40 输出样例2: 15.30 输出样例3: 454.75  思路:先把中缀表

中缀表达式求值问题(栈的应用)

1 #include <iostream> 2 #include<stdlib.h> 3 4 using namespace std; 5 6 #define STACK_INIT_SIZE 100 7 #define STACKINCREASE 10 8 9 //为了简化函数,数据栈和符号栈用了一种结构体(虽然我知道可以用共用体解决问题,嫌烦), 10 //由此导致的后果是接下来所有的运算过程中不允许出现小数,而且由于是利用ASCII表来储存整数, 11 //所以要求运算数以及运