矩阵乘法的运算量与矩阵乘法的顺序强相关。
例如:
A是一个50×10的矩阵,B是10×20的矩阵,C是20×5的矩阵
计算ABC有两种顺序:((AB)C)或者(A(BC)),前者需要计算15000次乘法,后者只需要3500次。
编写程序计算不同的计算顺序需要进行的乘法次数。
数据范围:矩阵个数:
1
≤
n
≤
15
1\le n\le 15
1≤n≤15,行列数:
1
≤
r
o
w
i
,
c
o
l
i
≤
100
1\le row_i,col_i\le 100
1≤rowi,coli≤100,保证给出的字符串表示的计算顺序唯一。
进阶:时间复杂度:
O
(
n
)
O(n)
O(n),空间复杂度:
O
(
n
)
O(n)
O(n)
输入多行,先输入要计算乘法的矩阵个数 n,每个矩阵的行数,列数,总共 2n 的数,最后输入要计算的法则;
计算的法则为一个字符串,仅由左右括号和大写字母(‘A’~‘Z’)组成,保证括号是匹配的且输入合法!
输出需要进行的乘法次数
输入:
3
50 10
10 20
20 5
(A(BC))
输出:
3500
首先要知道矩阵运算的过程和规律,
以 [ m , n ] [m, n] [m,n] 表示 m m m 行 n n n 列的矩阵,以 [ m , n ] ∗ [ n , p ] [m, n] * [n, p] [m,n]∗[n,p] 为例进行矩阵乘法规则说明:
因此,我们可以利用栈来进行判断和运算,遍历字符串,
可知字符串的长度为 n + 2 * ( n - 1),n 为矩阵个数。
#include <iostream>
#include <vector>
#include <map>
#include <stack>
using namespace std;
int main(){
int n;
while(cin >> n){
vector<vector<int>> m(n, vector<int>(2, 0)); // m[i][0] 表示行
for(int i = 0; i < n; ++i){
cin >> m[i][0] >> m[i][1];
}
stack<vector<int>> st;
int ans = 0;
for(int i = 0; i < 3*n-2; ++i){ // 字符串的长度为 n + 2*(n-1)
char ch;
cin >> ch;
if(ch == '('){ // 左括号不处理
continue;
}else if(ch == ')'){ // 右括号,对头两个矩阵进行操作
vector<int> a(2, 0);
vector<int> b(2, 0);
b = st.top(); // a * b
st.pop();
a = st.top();
st.pop();
ans += a[0] * a[1] * b[1]; // 计算次数为 a行 * a列 * b列
st.emplace(vector<int>{a[0], b[1]}); // 将计算后的新矩阵大小压入栈内
}else{
st.emplace(m[ch-'A']); // 字母,使对应的矩阵大小入栈
}
}
cout << ans << endl;
}
return 0;
}