矩阵链乘法
   求解矩阵链相乘问题时动态规划算法的另一个例子。给定一个n个矩阵的序列(矩阵链)<A1,A2,...,An>,我们希望计算它们的乘积  A1A2...An
   为了计算表达式,我们可以先用括号明确计算次序,然后利用标准的矩阵相乘算法进行计算。完全括号化(fully parenthesized):它是单一矩阵,或者是两个完全括号化的矩阵乘积链的积。
   例如如果有矩阵链为<A1,A2,A3,A4>,则共有5种完全括号化的矩阵乘积链。
   (A1(A2(A3A4)))、(A1((A2A3)A4))、((A1A2)(A3A4))、((A1(A2A3))A4)、((A1(A2A3))A4)
   对矩阵链加括号的方式会对乘积运算的代价产生巨大影响。我们先来分析两个矩阵相乘的代价。下面的伪代码的给出了两个矩阵相乘的标准算法,属性rows和columns是矩阵的行数和列数。

MATRIX-MULTIPKLY(A,B)
if A.columns≠B.rows 
	error "incompatible dimensions"
else let C be a new A.rows×B.columns matrix
	for i = 1 to A.rows
	     for j = 1 to B.columns
		  c(ij)=0
		   for k = 1 to A.columns
			 c(ij)=c(ij)+a(ik)*b(kj)
return C


    两个矩阵A和B只有相容(compatible),即A的列数等于B的行数时,才能相乘。如果A是p×q的矩阵,B是q×r的矩阵,那么乘积C是p×r的矩阵。计算C所需要时间由第8行的标量乘法的次数决定的,即pqr。
   以矩阵链<A1,A2,A3>为例,来说明不同的加括号方式会导致不同的计算代价。假设三个矩阵的规模分别为10×100、100×5和5×50。
   如果按照((A1A2)A3)的顺序计算,为计算A1A2(规模10×5),需要做10*100*5=5000次标量乘法,再与A3相乘又需要做10*5*50=2500次标量乘法,共需7500次标量乘法。
   如果按照(A1(A2A3))的顺序计算,为计算A2A3(规模100×50),需100*5*50=25000次标量乘法,再与A1相乘又需10*100*50=50000次标量乘法,共需75000次标量乘法。因此第一种顺序计算要比第二种顺序计算快10倍。
   矩阵链乘法问题(matrix-chain multiplication problem)可描述如下:给定n个矩阵的链<A1,A2,...,An>,矩阵Ai的规模为p(i-1)×p(i) (1<=i<=n),求完全括号化方案,使得计算乘积A1A2...An所需标量乘法次数最少。
   因为括号方案的数量与n呈指数关系,所以通过暴力搜索穷尽所有可能的括号化方案来寻找最优方案是一个糟糕策略。
可应用动态规划的方法

伪代码:

void PRINT_OPTIMAL_PARENS(int s[][M],int i,int j)
{
	if(i == j) cout<<"A"<<i;
	else
	{
		cout<<"(";
		PRINT_OPTIMAL_PARENS(s,i,s[i][j]);
		PRINT_OPTIMAL_PARENS(s,s[i][j]+1,j);
		cout<<")";
	}