矩阵链乘 Matrix Chain Multiplication - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题目描述
输入n个矩阵的维度和一些矩阵链乘表达式,输出乘法的次数。如果无法进行乘法,输出error.假定A是m*n矩阵,B是n*p矩阵,则乘法次数为m*n*p;如果A的列数不等于B的行数,则乘法无法进行。
假设你必须评估一种表达形如 ABCDE,其中 A,B,C,D,E是矩阵。既然矩阵乘法是关联的,那么乘法的顺序是任意的。然而,链乘的元素数量必须由你选择的赋值顺序决定。
例如,A,B,C分别是 50 * 10 ,10 * 20 和 20 * 5 的矩阵。现在有两种方案计算 A * B * C ,即(A * B) * C 和 A*(B * C)。
第一个要进行15000次基本乘法,而第二个只进行3500次。
你的任务就是写出一个程序判定以给定的方式相乘需要多少次基本乘法计算。
输入格式
输入包含两个部分:矩阵和表达式。 输入文件的第一行包含了一个整数 n(1 \leq≤ n \leq≤ 26), 代表矩阵的个数。接下来的n行每一行都包含了一个大写字母,说明矩阵的名称,以及两个整数,说明行与列的个数。
输出格式
对于每一个表达式,如果乘法无法进行就输出 " error "。否则就输出一行包含计算所需的乘法次数。
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=eval(input())
mt=[]
for i in range(n):
mt.append(input().split())def cal(x,y):#计算两个矩阵的乘法次数
res=[]
flag=0
if x[2]==y[1]:#可乘
multi=eval(x[1])*eval(x[2])*eval(y[2])
res.append(multi)
res.append(x[1])
res.append(y[2])
flag=1
if flag:
return res
else:
return False
def getmt(s):
alpha=[] #用来保存表达式中遇到的矩阵名,并将每次乘法运算后的矩阵压入栈中
times=0
for i in s:
if i.isalpha():
iloc=ord(i)-ord('A')
alpha.append(mt[iloc])
if i==")":
if cal(alpha[-2],alpha[-1]):
newr=cal(alpha[-2],alpha[-1])[1]
newc=cal(alpha[-2],alpha[-1])[2]
times+=cal(alpha[-2],alpha[-1])[0]
alpha.pop()
alpha.pop()
alpha.append(['new',newr,newc])
if len(s)!=1 and times==0:
return "error"
else:
return times
tgt=[]
while True:
try:
tgt.append(input())
except:
break
for t in tgt:
print(getmt(t))
参考资料
矩阵链乘(UVa 442) - Pink.Pig - 博客园 (cnblogs.com)
来存个档,哈~