UVA442 Matrix Chain Multiplication 栈的应用 好题

题意翻译

矩阵链乘

题目描述

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

​ 例如,A,B,C分别是 50 10 ,10 20 和 20 5 的矩阵。现在有两种方案计算 A C ,即(A B) C 和 A(B * C)。
第一个要进行15000次基本乘法,而第二个只进行3500次。

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

输入格式

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

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

输出格式

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

感谢@onceagain 提供翻译

题目描述

PDF

输入输出格式

输入格式:

 

 

输出格式:

 

 

输入输出样例

输入样例#1: 复制

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

输出样例#1: 复制

0
0
0
error
10000
error
3500
15000
40500
47500
15125

代码实现:

用一个栈维护,字母入栈,右括号计算,计算结果入栈,代码容易看懂

#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<cstdio>
using namespace std;
#define N 1100
typedef long long ll;

struct Ma
{
    int a,b;
}m[26];
stack<Ma>s;
int main()
{
    int n;
    while(scanf("%d",&n)!=-1)
    {

        for(int i=1;i<=n;i++)
        {
            string s;
            cin>>s;
            int k=s[0]-'A';
            scanf("%d%d",&m[k].a,&m[k].b);
        }
        string s1;
        while(cin>>s1)
        {

            int flag=0;
            int len=s1.length();
            int ans=0;
            for(int i=0;i<len;i++)
            {
                
                if(isalpha(s1[i]))
                    s.push(m[s1[i]-'A']);
                else if(s1[i]==')')
                {
                    Ma m1=s.top();s.pop();
                    Ma m2=s.top();s.pop();
                    if(m2.b!=m1.a)
                    {
                        flag=1;
                        break;
                    }
                    ans+=m2.a*m2.b*m1.b;
                  
                    Ma m3;
                    m3.a=m2.a;
                    m3.b=m1.b;
                    s.push(m3);
                }
            }
             if(flag) printf("error\n");
             else printf("%d\n",ans);
        }
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值