c++矩阵连乘的动态规划算法并输出_矩阵连乘

问题描述:

给定n个矩阵A1,A2,…,An,其中,Ai与Aj+1是可乘的,i=1,2,…,n-l。

你的任务是要确定矩阵连乘的运算次序,使计算这n个矩阵的连乘积A1A2…An时总的元素乘法次数达到最少。

例如:3个矩阵A1,A2,A3,阶分别为10×100、100×5、5×50,计算连乘积A1A2A3时按(A1A2)A3所需的元素乘法次数达到最少,为7500次。

输入

测试数据有若干组,每组测试数据有2行。

每组测试数据的第1行是一个整数n,(0<n<20),第2行是n+1个正整数p0、p1、p2、…、pn,这些整数不超过100,相邻两个整数之间空一格,他们表示n个矩阵A1,A2,…,An,的阶pi-1´pi,i=1,2,…,n。

输入直到文件结束。

输出

对输入中的每组测试数据,输出2行。先在一行上输出“Case #”,其中“#”是测试数据的组号(从1开始),再在第2行上输出计算这n个矩阵的连乘积A1A2…An时最少的总的元素乘法次数,再空一格,接着在同一行上输出矩阵连乘的添括号形式。

注意:最外层括号应去掉。

实验结果:

输入样例

3

10 100 5 50

4

50 10 40 30 5

输出样例

Case 1

7500 (A1A2)A3

Case 2

10500 A1(A2(A3A4))

程序代码如下:

#include<iostream>

#include <fstream>

#include <cassert>

#include <string>

#include <sstream>

using namespace std;

const int N=100;

int m[N][N],s[N][N];

void PrintAnswer(int i,int j)

{

if(i==j)

cout<<"A"<<i;

else

{

cout<<"(";

PrintAnswer(i,s[i][j]);

PrintAnswer(s[i][j]+1,j);

cout<<")";

}

}

void Matrix_Multi(int *p,int length)

{

int n=length-1;

int l,i,j,k,q=0;

//m[i][i]只有一个矩阵,相乘次数为零,所以m[i][i]=0

for(i=1;i<length;i++)

{

m[i][j]=0;

}

for(l=2;l<=n;l++) //宽度从2到n

{

for(i=1;i<=n-l+1;i++)

{

j=i+l-1; //以i为起始位,j为末位,长度为l

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];

if(q<m[i][j])

{

m[i][j]=q;

s[i][j]=k;

}

}

}

}

}

void readTxt(string file)

{

ifstream infile;

infile.open(file.data());

assert(infile.is_open());

string s;

int i=1;

while(getline(infile,s))

{

int a=atoi(s.c_str());

getline(infile,s);

istringstream tmp(s);

int x[a+1];

for(int i=0;i<=a;i++)

{

tmp>>s;

x[i]=atoi(s.c_str());

}

Matrix_Multi(x,a+1);

cout<<"Case "<<i<<endl;

i++;

cout<<m[1][a]<<" ";

PrintAnswer(1,a);

cout<<endl;

}

infile.close();

}

int main()

{

readTxt("input.txt");

return 0;

}

运行结果:

c22d8106872eec4c0b9af3be7874ae4c.png

思路详解:

https://blog.csdn.net/qq_32919451/article/details/80643118​blog.csdn.net
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值