题目难度:★★
对于矩阵链乘法这道题目,我们先明确一个概念:
对于n各需要相乘的矩阵所构成的(链)<A1,A2,...,An>,要计算其乘积A1A2...An。
我们需要对其加上n-1个括号,来确定其运算顺序。
明白括号概念之后,我们还需明白何为矩阵相乘。
矩阵相乘或不如称为纵横相乘,意思就是对于p*q,以及q*r的两个矩阵,对于第一个矩阵的p行,对应乘以第二个矩阵的r列,所得到的一个p*r的矩阵,就是矩阵相乘的结果。
例:
而后,我们还需明白一个最重要的概念:对于矩阵链乘法一题,其核心思想是要确定一个具有最小代价的矩阵相乘顺序,而并非要像矩阵相乘一样,把n个矩阵一一相承。
例:
所以,因此我们可以确定,问题最终要求的是一个最优解,那么我们来看此问题是否具有最优子结构,也就是问题的一个最优解是相当于其子问题的最优解。
对于矩阵列乘法这个问题:我们用m(i,j)表示对矩阵Ai,Ai+1..Aj的相乘的最优解。如果这个问题在i<>j的时候,可以对Ai,Ai+1..Aj在成Ak与Ak+1之间拆分。(i<=k<j)
亦即,对于某个存在的k值,首先计算Ai..k和Ak+1..j的最优值,然后把他们相乘之后再得到的一个值加上,就是m(i,j)里面的一个决策。所以,我们可以知道,当Ai..k和Ak+1..j相乘得到的最终结果值得时候,虽然不一定对于Ai..j是最优解,但是必然是其中的某一个解,如果对于这个解不是最优,则当k等于其余任何(i,j)之内的值得时候,必然会得到一个Ai..j问题的最优解。
当得知问题具有最优子结构的时候,我们还可以推断出此问题具有无后效性的原则,y因为其无论如何改变括号,A1..n的顺序这n个数始终没变,也就是说对于Ai..j,j-i+1个矩阵相乘得到的结果,不管最终这个结果的答案是多少,都不会对A链里其余矩阵产生任何影响。
我们需要解决的最后一个问题就是如何划分状态了。也就是定义递归解。在确定最优解时候用的m[i,j]计算矩阵最优解,其实就是一个状态。经过上面的推导,也很容易想到状态转移方程为:
这里Ai是由pi-1*pi得来的,所以加上pi-1pkpj的值,也就是当把Ai..k和Ak+1..j的矩阵合并之后得到的结果。这里就是矩阵相乘的结果。
伪代码如下:
根据伪代码中存储的s的值,我们还可以通过递归输出,来输出最后加括号的结果。
伪代码如下:
当然,我们还可以用记忆化的方法,来求出最终的答案: