Description
| | |
| 给定n个矩阵{A1,A2,…,An},其中Ai与Ai+1是可乘的,i=1,2,…,n-1。要算出这n个矩阵的连乘积A1A2…An。由于矩阵乘法满足结合律,故计算矩阵的连乘积可以有许多不同的计算次序。这种计算次序可以用加括号的方式来确定。若一个矩阵连乘积的计算次序完全确定,也就是说该连乘积已完全加括号,则可以依此次序反复调用2个矩阵相乘的标准算法计算出矩阵连乘积。完全加括号的矩阵连乘积可递归地定义为: (1)单个矩阵是完全加括号的; (2)矩阵连乘积A是完全加括号的,则A可表示为2个完全加括号的矩阵连乘积B和C的乘积并加括号,即A=(BC)。对于给定的相继n个矩阵{A1,A2,…,An}(其中矩阵Ai的维数为pi-1×pi,i=1,2,…,n),如何确定计算矩阵连乘积A1A2…An的计算次序(完全加括号方式),使得依此次序计算矩阵连乘积需要的数乘次数最少。 | |
| | |
Input
| | |
| 第1行为n值,表示n个矩阵
接下来的n行,每行一个数值,顺序表示Ai(1≤i≤n)矩阵的行数
最后一行表示An矩阵的列数 | |
| | |
Output
Sample Input
Sample Output
#include<iostream>
using namespace std;
#define N 100
int p[N];
int m[N][N];
int main()
{
int n,i,j,k,min,cut;
while(cin>>n)
{
for(i=1;i<=n+1;i++)
cin>>p[i];
for(i=1;i<=n;i++)
m[i][i]=0;//填充正对角线
for(j=2;j<=n;j++)//表示除正对角线外,需要做多少次对角线填充
{
for(i=1,k=j;i<n,k<=n;i++,k++)//遍历对角线元素
{
min=m[i][i]+m[i+1][k]+p[i]*p[i+1]*p[k+1];
for(cut=i+1;cut<k;cut++)//分割,取最小值
{
if(m[i][cut]+m[cut+1][k]+p[i]*p[cut+1]*p[k+1]<min)
min=m[i][cut]+m[cut+1][k]+p[i]*p[cut+1]*p[k+1];
}
m[i][k]=min;
}
}
cout<<m[1][n]<<endl;
}
return 0;
}