矩阵连乘问题:动态规划——(C++)

问题描述:矩阵A和B可乘的条件是A的列数等于B的行数。若A是一个p×q矩阵,B是一个q×r矩阵,则其乘积C=AB是一个p×r矩阵。在计算矩阵乘积的标准算法中,主要计算量为p×q×r次数乘。
由于矩阵的乘法满足结合律,故计算矩阵的连乘积有许多不同的计算次序。
给定n个矩阵{ A1,A2,……,An },其中Ai和Ai+1是可乘的,i=1,2,……,n-1,求计算其连乘积A1×A2×……×An的最小乘法次数

输入格式:

第1行为一个正整数n,表示n个矩阵相乘,n≤100。
第2行为n+1个整数p0p1……pn,其中pi-1pi为矩阵Ai的行数和列数。

样例输入:

C++代码:

#include<iostream>
using namespace std;

#define MAX 100
int m[MAX][MAX];
int s[MAX][MAX];

void MatrixChain(int *p, int n)
{
	for (int i = 1; i <= n; i++)
		m[i][i] = 0;
	for (int r = 2; r <= n; r++)
		for (int i = 1; i <= n - r + 1; i++) {
			int j = i + r - 1;
			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; }
			}
		}

}

void traceback(int i, int j)
{
	if (i == j)
		cout << "A" << i;
	else if (i == j - 1)
		cout << "(A" << i << "A" << j << ")";
	else
	{
		cout << "(";
		traceback(i, s[i][j]);
		traceback(s[i][j] + 1, j);
		cout << ")";
	}

}


int main()
{
	int t;
	int p[MAX + 1];//记录输入矩阵
	cin >> t;//输入矩阵的数量
	for (int i = 0; i <= t; i++)
		cin >> p[i];

	MatrixChain(p, t);
	cout << m[1][t]<<endl;
	system("PAUSE");
	return 0;
}

解析:

解题的过程是求解矩阵连乘的最乘法次数,以及输出最优计算次序。

在这段代码,定义了MatrixChain函数和traceback函数,用于求解和输出最小乘法次数和最优计算次序。其中,MatrixChain函数使用动态规划的思想,根据所有可能的计算次序,计算出每种计算次序的乘法次数,从而得到最小乘法次数。而traceback函数则根据保存的信息,递归输出最优计算序。

具体地说,在MatrixChain函数中,首先初始化m数组为0,表示每个矩阵自身的乘法次数为0。然后使用两层循环来计算m和s数组的值。 外层循环变量r表示连乘的长度,从2到n(矩阵数量)。内层循环变量i表示起始位置,从1到n-r+1。每计算m[i][j]和s[i][j]的值,其中j=i-1。 通过一个内层循环变量k,遍历从i+1到j-1的所有中间位置,计算以k为分割点的连乘乘法次数t。如果t小于当前的m[i][j],更新m[i][j]和s[i][j]的值。 最终,输出m[1][t],即A1到At的连乘最小乘法次数。 在traceback函数中,根据保存在s数组中的分割点信息,递归地输出矩阵的乘法次序。如果i等于j,输出Ai;如果i等于j-1,输出(AiAj);否则,输出(Atraceback(i, s[i][j])traceback(s[i][j] + 1, j))。 最后,在main函数中输入矩阵数量和每个矩阵的尺寸信息,调用MatrixChain函数求解最小乘法次数输出结果。然后调用traceback函数输出最优计算次序。 希望以上解答对你有帮助!
 

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

seahallo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值