#include "stdafx.h"
#include<stdio.h>
#define r1 3
#define r2 2
#define c1 2
#define c2 3
#define n 6
int m[n+1][n+1];
int s[n+1][n+1];
//计算矩阵的值
void matrix_matiply(int a[][2], int b[][3]) //ab是二维数组 a[r1][c1] b[r2][c2]
{
int c[r1][c2];
int k,i,j;
if (c1 != r2)
{
printf("incompaticle dimensions!");
}
else
{
for (i = 0; i <r1; i++)
{
for (j = 0; j < c2; j++)
{
c[i][j] = 0; //数组c全部赋值0
for (k = 0; k < c1; k++)
c[i][j] = c[i][j] + a[i][k] * b[k][j]; //数组c开始计算
}
}
}
for (i = 0; i < c2; i++)
{
for (j = 0; j < r1; j++)
{
printf("%d ", c[i][j]);
}
printf("\n");
}
}
void matrix_chain_order(int *p)
{
//计算矩阵所需标量乘法运算次数的最小值
int i, l, j, k,q;
//辅助存放取得最优代价时k的值
for (i = 1; i <= n; i++)
{
m[i][i] = 0; //只有一个元素,令次数为0
}
for (l = 2; l <= n; l++) //当前链的长度2,3,4....n
{
for (i = 1; i <= n - l + 1; i++)
{
j = i + l-1;
m[i][j] = 0x7fffffff; //假设每两个矩阵乘法都需要无穷大的次数
for (k = i ; k <=j - 1; k++)
{
q = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j]; //从k出划分括号,计算Ai-Ak,Ak+1-Aj的次数之和 这里p[i-1]是从0开始的,所以p数组不用多设置一位数了
if (q < m[i][j]) //如果划分了计算次数小于不划分,那么就划分并记录
{
m[i][j] = q;
s[i][j] = k;
}
}
}
}
}
//把s[j][j]中存储的信息即在哪里加括号,把括号输出
void print_optimal_parens(int s[][7], int i, int j) //s[i][j]存的是从哪里分开加个括号
{
if (i == j)
{
printf("A%d", i);
}
else
{
printf("(");
print_optimal_parens(s, i, s[i][j]);
print_optimal_parens(s, s[i][j] + 1, j);
printf(")");
}
}
int main()
{
int a[r1][c1] = { 1,2, 3,4, 5,6 };
int b[r2][c2] = { 10,11,12, 13,14,15 };
int p[7] = { 30,35,15,5,10,20,25 };
printf("计算出的矩阵乘积结果是:------------\n");
matrix_matiply(a, b);
matrix_chain_order(p);
printf("A2-A5最快的划分是:---------:'%d'次\n",m[2][5]);
printf("划分的形式是:---------:\n");
print_optimal_parens(s, 1, 6);
return 0;
}
还是那个老问题,数组下标从0开始真的很麻烦呀。就给s数组和m数组多设置了一位,循环的时候都是从下标1开始循环的,前面的下标为0没有赋值,也没有用到。这里的p数组看具体代码本来就是从下标0开始的就不用开一个空间了。
因为做了这种处理,就没有像书上的p的长度比个数多一位了。