例题6-3 UVA442 Matrix Chain Multiplication(39行AC代码)

紫书刷题进行中,题解系列【GitHub|CSDN

例题6-3 UVA442 Matrix Chain Multiplication(39行AC代码)

题目大意

求矩阵在不同乘法顺序下的乘法次数,假设矩阵A:a*b,矩阵B:b*c,那么A*B的乘法总次数为a*b*c

思路分析

矩阵链相乘是动态规划中的典例,可快速计算相乘次数最少的相乘方式,这里比较简单,只需求给定顺序的相乘次数,主要在于括号处理,可用栈轻松实现。

由题目给出的EBNF可知,每个括号内部一定只有两个矩阵,因此同一级括号内部个数确定,无需在存储括号。即遇到矩阵压栈,遇到右括号将弹出两个栈顶,计算后再次压入,遇到左括号不处理。

若是每个括号内矩阵个数未知,则必须根据括号来标记同一层级的位置

AC代码(C++11,stack)

#include<bits/stdc++.h>
using namespace std;
int n, a, b;
char ch;
map<char, pair<int,int> > mp; // 矩阵->(行数,列数)
int simu(string s) { // 模拟相乘过程,错误返回-1,否则返回次数
    int ans = 0;
    stack<pair<int,int> > stk; // 矩阵栈,第一二维
    bool isErr=false; // 标记是否有错误
    for (auto c : s) {
        if (isalpha(c)) stk.push(mp[c]); // 矩阵
        if (c == ')') { // 出栈计算
            auto p1 = stk.top(); stk.pop();
            auto p2 = stk.top(); stk.pop();
            if (p2.second != p1.first) { // 错误
                isErr = true;
                break;
            }
            ans += p2.first*p2.second*p1.second; // 运算次数
            stk.push({p2.first, p1.second}); // 重新压入
        }
    }
    return ans = (isErr) ? -1 : ans;
}
int main() {
    scanf("%d", &n);
    while (n --) {
        getchar();
        scanf("%c %d %d", &ch, &a, &b);
        mp[ch] = {a,b};
    }
    string s;
    while (cin >>s) {
        int ans = simu(s);
        if (ans == -1) puts("error");
        else printf("%d\n", ans);
    }
    return 0;
}
发布了128 篇原创文章 · 获赞 87 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_40738840/article/details/104286216