矩阵链乘 UVa442 Python实现

矩阵链乘 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)

来存个档,哈~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值