/*
从连乘矩阵个数为2开始计算每次的最小乘次数为
m[i][j]: m[0][1] m[1][2] m[2][3] m[3][4] m[4][5]
其中m[0][1]表示第一个矩阵与第二个矩阵的最小乘次数
然后再计算再依次计算
连乘矩阵个数为3:m[0][2] m[1][3] m[2][4] m[3][5]
连乘矩阵个数为4:m[0][3] m[1][4] m[2][5]
连乘矩阵个数为5:m[0][4] m[1][5]
连乘矩阵个数为6:m[0][5] //即最后我们要的结果
*/
/*测试数据*/
//输入:6
// 30 35 15 5 10 20 25
//输出:6 15125
#include<cstdio>
#include<algorithm>
using namespace std;
int n; //需要矩阵连乘的个数
int a[100003]; //记录n个矩阵的行列数
int Trace(int a[100003])
{
int m[n][n];
for(int i=0; i<n; i++) //单一矩阵的最小乘次都置为0
{
m[i][i] = 0;
}
for(int c=2; c<=n; c++) //c为连乘矩阵的个数(c>=2)
{
for(int i=0; i<=n-c; i++)
{ //i表示连乘矩阵中的第一个
int j = i + c - 1; //j表示连乘矩阵中的最后一个
m[i][j] = 1000000; //m[i][j]为矩阵连乘的次数,初始化为较大的值,便于比较
for(int k=i; k<j; k++)
{
/*
在第一个与最后一个之间寻找最合适的断开点,
注意,这是从i开始
即要先计算两个单独矩阵相乘的乘次
*/
int t = m[i][k] + m[k+1][j] + a[i] * a[j+1] * a[k+1];
//用t记录每次矩阵连乘的次数
if(t < m[i][j])
{
m[i][j] = t; //更新矩阵连乘的次数
}
}
}
}
printf("%d个矩阵需要的连乘次为%d\n", n, m[0][n-1]);
}
int main()
{
printf("请输入需要矩阵连乘的个数:\n");
scanf("%d",&n);
printf("请依次输入%d个矩阵的行列数:\n", n);
for(int i = 0; i <= n; i++)
{
scanf("%d", &a[i]);
}
Trace(a); //调用函数,传递数组参数
return 0;
}