矩阵链乘法,特别要求举例时采用不同于讲义的数据进行推导
矩阵A和矩阵B能够相乘,只有当矩阵A和矩阵B相容。矩阵链乘法的前提就是降低矩阵的乘法规模。之所以可以这样,是因为矩阵相乘满足结合律。我们可以这样去想,我们使用使用一个分割线,把矩阵链分成两份,一份左,一份右,如果左右的矩阵链的乘法次数最少,那么分割线处的乘法次数有如下等式:
#include <stdio.h>
void print(int s[][100], int i, int j) {//括号化方案
if (i == j) {
printf("A%d", i);
}
else {
printf("(");
print(s, i, s[i][j]);
print(s, s[i][j] + 1, j);
printf(")");
}
}
void MatrixChain(int p[100], int m[100][100], int s[100][100], int n) {
int r, i, j, k, t;
for (r = 2; r <= n; r++) {//r为当前问题规模(长度)
for (i = 1; i <= n - r + 1; i++) { //i的起点不断变化,各种r长
j = i + r - 1; //不同终点
m[i][j] = m[i + 1][j] + p[i - 1] * p[i] * p[j];//划分为Ai(Ai+1...Aj),此时k=i
s[i][j] = i;//初始化 s位置为i
for (k = i + 1; k <= j - 1; k++) {
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;
}
}
}
}
}
int main() {
int p[100], m[100][100], s[100][100], n, i;
printf("输入问题规模(长度): ");
scanf("%d", &n);
printf("输入向量: ");
for (i = 0; i < n; i++) {
scanf("%d", &p[i]);
}
MatrixChain(p, m, s, n - 1);
printf("最小总次数为: %d\n", m[1][n - 1]);
printf("括号化方案为:");
print(s, 1, n - 1);
}