矩阵链乘 Matrix Chain Multiplication

目录

目录

1.题目

题目描述

输入格式

输出格式

样例输入

样例输出

题目大意 

2.分析

3.AC代码


1.题目

题目描述

假设你必须评估一种表达形如 A∗B∗C∗D∗EA∗B∗C∗D∗E,其中 AA,BB,CC,DD,EE是矩阵。既然矩阵乘法是关联的,那么乘法的顺序是任意的。然而,链乘的元素数量必须由你选择的赋值顺序决定。

​ 例如,AA,BB,CC分别是 50∗1050∗10 ,10∗2010∗20 和 20∗520∗5 的矩阵。现在有两种方案计算 A∗B∗CA∗B∗C ,即(A∗B)∗C(A∗B)∗C 和 A∗(B∗C)A∗(B∗C)。
第一个要进行1500015000次基本乘法,而第二个只进行35003500次。

​ 你的任务就是写出一个程序判定以给定的方式相乘需要多少次基本乘法计算。

输入格式

​ 输入包含两个部分:矩阵和表达式。
输入文件的第一行包含了一个整数 n(1≤n≤26)n(1≤n≤26), 代表矩阵的个数。接下来的nn行每一行都包含了一个大写字母,说明矩阵的名称,以及两个整数,说明行与列的个数。
第二个部分严格遵守以下的语法:

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

Copy

Paintext

输出格式

对于每一个表达式,如果乘法无法进行就输出error。否则就输出一行包含计算所需的乘法次数。

样例输入
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

题目大意 

输入题目指定数量个矩阵的维度和一个矩阵链乘的表达式,输出乘法的次数,如果乘法无法进行,则输出 errorerror

2.分析

栈对表达式求值有着特殊的作用,本题表达式简单,可以用一个栈来完成,遇到字母时入栈,遇到右括号时出栈并且计算,之后算出的结果入栈。

3.AC代码

#include<bits/stdc++.h>
using namespace std;
void read();
void cal(string s);
struct Node
{
	int x;
	int y;
	Node(){}
};
const int MAXN = 26 + 4;
Node m[MAXN];
int main()
{
	memset(m,0,sizeof(m));
	int n;
	cin>>n;
	getchar();
	while (n--)
	{
		read();
	}
	string s;
	while (cin >> s)
	{
		cal(s);
	}
	return 0;
}
void cal(string s)
{
	int sum=0;
	stack<Node> st;
	if (s.length()==1)  
	{
		cout<<sum<<endl;
		return;
	}
	for(int i=0;i<s.length();i++)
	{
		if(s[i]=='(')
			continue;
		else if(s[i]==')') 
		{
			Node a,b,t;
			b=st.top();st.pop();
			a=st.top();st.pop();
			if(a.y!=b.x)  
			{
				cout<<"error"<<endl;
				return;
			}
			else
			{
				t.x=a.x;
				t.y=b.y;
				st.push(t);
				sum+=a.x*a.y*b.y;
			}
		}
		else
			st.push(m[s[i]-'A']);
	}
	cout<<sum<<endl;
}
 
void read()
{
	string s;
	int a,b;
	cin>>s>>a>>b;
	m[s[0]-'A'].x=a;
	m[s[0]-'A'].y=b;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谢铭轩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值