1. 程式人生 > >UVa442 例題6-3 矩陣鏈乘(Matrix Chain Multiplication)

UVa442 例題6-3 矩陣鏈乘(Matrix Chain Multiplication)

題目大意:

    輸入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;
}