原题链接:UVa-442
题目大意:
输入n个矩阵维度和一些矩阵链乘表达式,输出乘法次数。
解题思路:
本题的思路很清晰,先读取各个矩阵维度。然后根据输入的矩阵链乘表达式进行计算。矩阵链乘表达式计算时需要用到栈。当遇到')'时,从表达式中取出两个矩阵进行链乘,之后再存入栈中。直到计算到完成计算。
需要注意的就是从栈中取出矩阵进行计算的时候应该使用 先取出矩阵的y与后取出矩阵的x进行比较能不能计算。因为栈本来就是先进后出的。还有就是单个矩阵时,不需要计算直接输出。
感悟:
在算法课上也讲过一道矩阵链乘的题,不过那道题是让求最优的加括号方式,比这道题有难度。有机会可以再看看。
代码:
#include<iostream>
#include<cstring>
#include<string>
#include<stack>
using namespace std;
void read();
void cal(string s);
struct Matrix
{
int x;
int y;
Matrix(){}
};
const int MAXN = 26 + 4;
Matrix m[MAXN];
int main()
{
memset(m, 0, sizeof(m)); //初始化m
int n;
cin >> n;
getchar();
while (n--)
{
read();//读入输入给得n个矩阵
}
string s;
while (cin >> s)
{
cal(s);//计算矩阵链乘表达并输出
}
return 0;
}
void cal(string s)
{
int sum = 0;
stack<Matrix> st;
if (s.length() == 1) //如果只有一个矩阵,则计算次数为0
{
cout << sum << endl;
return;
}
for (int i = 0; i < s.length(); i++)
{
if (s[i] == '(')
continue;
else if (s[i] == ')') //遇到')'需要计算栈内最上层的两个矩阵
{
Matrix a, b, t;
b = st.top(); st.pop();//后入的先出
a = st.top(); st.pop();
if (a.y != b.x) //无法计算
{
cout << "error" << endl;
return;
}
else //计算生成的新矩阵然后放入栈中
{
t.x = a.x;
t.y = b.y;
st.push(t);
sum += a.x * a.y * b.y;
}
}
else
st.push(m[s[i] - 'A']);
}
cout << sum << endl;
}
void read()
{
string s;
int a,b;
cin >> s >> a >> b;
m[s[0] - 'A'].x = a;
m[s[0] - 'A'].y = b;
}