矩阵的乘法定义如下:设A是m×p的矩阵,B是p×n的矩阵,则A与B的乘积为m×n的矩阵,记作C=AB,其中,矩阵C中的第i行第j列元素c
ij
可以表示为:c
ij
=Σ
k=1
p
a
ik
×b
kj
=a
i1
b
1j
+a
i2
b
2j
+⋯+a
ip
b
pj
.
当多个矩阵相乘时,采用不同的计算顺序所需的乘法次数不相同。例如,A是50×10的矩阵,B是10×20的矩阵,C是20×5的矩阵, 计算ABC有两种方式:(AB)C和A(BC),前一种需要15000次乘法计算,后一种则只需3500次。
设A
1
,A
2
,…,A
n
为矩阵序列,A
i
是阶为P
i−1
∗P
i
的矩阵(1≤i≤n)。试确定矩阵的乘法顺序,使得计算A
1
A
2
…A
n
过程中元素相乘的总次数最少。
输入格式:
每个输入文件为一个测试用例,每个测试用例的第一行给出一个正整数n(1≤n≤100),表示一共有n个矩阵A
1
,A
2
,…,A
n
,第二行给出n+1个整数P
0
,P
1
…P
n
,以空格分隔,其中1≤P
i
≤100(0≤i≤n),第i个矩阵A
i
是阶为P
i−1
∗P
i
的矩阵。
输出格式:
获得上述矩阵的乘积,所需的最少乘法次数。
输入样例:
在这里给出一组输入。例如:
5
30 35 15 5 10 20
输出样例:
在这里给出相应的输出。例如:
11875
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 10000;
int p[maxn], n;
int m[maxn][maxn], s[maxn][maxn]; // 记录最小乘法运算次数,和最后一次运算的位置
int r; // r为链长
int MatrixChain(int P[], int n)
{
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
m[i][j] = 0;
s[i][j] = i;
}
}
for(int r = 2; r <= n; r++)
{
for(int i = 1; i <= n - r + 1; i++) // 前边界为i
{
int j = i + r - 1; // 前边界i链长为r的后边界为j
m[i][j] = m[i + 1][j] + p[i-1] * p[i] * p[j];
s[i][j] = i; //记录分隔位置;
for(int k = i + 1; k < j; k++)
{
int t = m[i][k] + m[k + 1][j] + p[i-1] * p[k] * p[j];
if(t < m[i][j])
{
m[i][j] = t;
s[i][j] = k;
}
}
}
}
return m[1][n];
}
int main()
{
cin >> n; //n个矩阵
for(int i = 0; i <= n; i++)
{
cin >> p[i];
}
cout << MatrixChain(p, n)<<endl;
return 0;
}