矩阵链相乘实例

题目描述

零崎有很多朋友,其中有一个叫jhljx。

jhljx大家很熟悉了,他数学不好也是出了名的,大家都懂。

现在jhljx遇到了矩阵乘法,他当时就懵了。数都数不清的他,矩阵乘法怎么可能会算的清楚呢?虽然零崎觉得还不如让你们来算,不过好歹也要给jhljx个面子,给她留下一个证明自己数学实力的机会。为了减小jhljx的计算量,让他赶快算出不正确答案来(估计他算上几遍都不一定能出一个正确答案),零崎请你们帮助jhljx。

输入

多组输入数据。

每组数据以N开始,表示矩阵链的长度。接下来一行N+1个数表示矩阵的行/列数。

1<=N<=300

输出

对于每组样例,输出一行最少运算次数的方案,每两个矩阵相乘都用“()”括起来,详见样例

如果存在多种解决方案,最终输出结果选取先计算左边的矩阵,详见Hint

输入样例

3
10 30 5 60
3
10 20 5 4

输出样例

((A1A2)A3)
((A1A2)A3)

Hint

对于输入的第二组数据,

如果计算顺序为((A1A2)A3),结果为10×20×5 + 10×5×4= 1200,

如果计算顺序为A1(A2A3), 结果为20×5×4 + 10×20×4 = 1200

那么输出结果选取第一个

题目来源:http://biancheng.love/contest/17/problem/D/index

题目注意事项:如果存在多种解决方案,最终输出结果选取先计算左边的矩阵

下面给出实现代码:

 1 #include <bits/stdc++.h>
 2 #define max_size 400
 3 #define INF 100000000
 4 long long s[max_size][max_size];//保存构造最优解信息
 5 long long p[max_size];//矩阵规模的记录
 6 long long m[max_size][max_size];//记录最优值
 7
 8 void  matrix_chain_order(int n)
 9 {
10     for(int i=1;i<=n;i++)
11     {
12         m[i][i]=0;//初始化最优值(起始于1,结束于n)
13     }
14     for(int l=2;l<=n;l++)//l表示矩阵的长度
15     {
16         for(int i=1;i<=n-l+1;i++)
17         {
18             int j=i+l-1;
19             m[i][j]=INF;
20             s[i][j]=0;
21             for(int k=j-1;k>=i;k--)//解决方案优先选取先左边的矩阵
22             {
23                 int q=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
24                 if(q<m[i][j])
25                 {
26                     m[i][j]=q;
27                     s[i][j]=k;
28                 }
29             }
30         }
31     }
32 }
33
34 void print_optimal_parents(int i,int j)//打印最优解的结果
35 {
36     if(i==j)
37         printf("A%d",i);
38     else
39     {
40             printf("(");
41             print_optimal_parents(i,s[i][j]);
42             print_optimal_parents(s[i][j]+1,j);
43             printf(")");
44     }
45 }
46
47 int main()
48 {
49     int n;
50     while(~scanf("%d",&n))
51     {
52         memset(p,0,sizeof(p));
53         for(int i=0;i<=n;i++)
54         {
55             scanf("%lld",&p[i]);
56         }
57         matrix_chain_order(n);
58         print_optimal_parents(1,n);
59         printf("\n");
60     }
61 }

对实现过程的详细解答请见http://www.cnblogs.com/Anker/archive/2013/03/10/2952475.html

时间: 2024-10-23 00:14:42

矩阵链相乘实例的相关文章

算法导论 之 动态规划 - 矩阵链相乘

1 引言 在大学期间,我们学过高等数学中的线性规划,其中有关于矩阵相乘的章节:只有当矩阵A的列数与矩阵B的行数相等时,A×B才有意义.一个m×n的矩阵A(m,n)左乘一个n×p的矩阵B(n,p),会得到一个m×p的矩阵C(m,p).矩阵乘法满足结合律,但不满足交换律. 假设现要计算A×B×C×D的值,因矩阵乘法满足结合律,不满足交换律,即:A.B.C.D相邻成员的相乘顺序不会影响到最终的计算结果,比如: A×(B×(C×D)).A×((B×C)×D).(A×B)×(C×D).A×(B×C)×D.

UVA 348 &amp; ZOJ 1276 Optimal Array Multiplication Sequence(dp , 矩阵链相乘问题)

Optimal Array Multiplication Sequence Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Description Given two arrays A and B, we can determine the array C = AB using the standard definition of matrix multiplication: The number of

矩阵链相乘问题

问题描述 给定n个矩阵A1,A2 ,...,An,相邻的矩阵是可乘的,如何确定一个最优计算次序,使得以此次序计算需要的数乘次数最少? 计算次序对计算性能的影响: 假设n=3,A1,A2,A3的维数分别为10×100,100×5,5×50.考察A1×A2×A3需要的数乘次数,有以下 两种计算方式: (1)(A1×A2)×A3:10×100×5+10×5×50=7500 (2) A1×(A2×A3):100×5×50+10×100×50=75000 通过这个简单的例子足以说明,矩阵的计算次序对计算性

算法导论--矩阵链相乘

#include<iostream> using namespace std; /* 计算括号化方案数:标量乘法作为代价衡量,应该使标量乘法尽可能少. m[i,j]表示Ai.....Aj所需标量乘法的最小值. i=j 时只有一个矩阵,无需分割 m[i,i]=0; 采用自底向上的方式: */ int m[100][100]; int p[]={30,35,15,5,10,20,25}; int bottomcut(int n){ int t; for(int l=2;l<=n;l++){

动态规划-矩阵链乘法

问题描述: 给定由n个要相乘的矩阵构成的序列(链)<A1,A2,...,An>,要计算乘积A1A2...An,可以将两个矩阵相乘的标准算法作为一个子程序,通过加括号确定计算的顺序(对同一矩阵链,不同的计算顺序所需要的计算次数大不相同). 目标问题:给定n个矩阵构成的矩阵链<A1,A2,...,An>,其中,i=1,2,...,n,矩阵Ai的维数为pi-1×pi,对乘积A1A2...An以一种最小计算次数加全部括号. 穷尽搜索: 令P(n)表示一串n个矩阵可能的加全部方案数.当n=1

矩阵链乘最优化实现

矩阵链乘最优化算法(括号化算法),关键要找到A[i]...A[j]矩阵链相乘做最少乘法次数(存在m[][]中)的相乘顺序,记录在矩阵s[][]中.再利用递归定义矩阵链乘算法.递归的出口是只有一个矩阵(直接返回)或者两个矩阵(返回相乘后的结果矩阵)的情况. 1 //#include"OptimalMatrixMultiplication.h" 2 #include<iostream.h> 3 #include<stdio.h> 4 #include<stdl

动态规划之矩阵链乘法

矩阵链相乘 矩阵链乘法 求解矩阵链相乘问题时动态规划算法的另一个例子.给定一个n个矩阵的序列(矩阵链)<A1,A2,...,An>,我们希望计算它们的乘积 A1A2...An ?两个矩阵A和B只有相容(compatible),即A的列数等于B的行数时,才能相乘.如果A是p×q的矩阵,B是q×r的矩阵,那么乘积C是p×r的矩阵.计算C所需要时间由第8行的标量乘法的次数决定的,即pqr. ? ?以矩阵链<A1,A2,A3>为例,来说明不同的加括号方式会导致不同的计算代价.假设三个矩阵的

动态规划 - 矩阵链的乘法问题

1.1具体实例 1.2子问题的划分和递推方程 2.动态规划算法的递归实现 3.动态规划算法的迭代实现 4.动态规划算法的要素 这里用矩阵链的乘法问题来说明动态规划算法的设计要素. \(A_1,A_2,..,A_n\)表示\(n\)个矩阵的序列,其中\(A_i\)为\(P_{i-1} \times P_i\)阶矩阵,\(i=1,2,...,n\). 向量\(P=<P_0,P_1,P_2..P_i>\)表示矩阵链的输入,其中\(P_0\)是\(A_1\)的行数,\(P_1\)是\(A_1\)的列数

动态规划之矩阵链

dp有很多个经典应用,矩阵链是其中一个. 对于我这种数学不好的人,需要回顾矩阵性质. 若矩阵A的维数是p×q,矩阵B的维数是q×r,则A与B相乘后所得矩阵AB的维数是p×r.按照矩阵相乘的定义,求出矩阵AB中的一个元素需要做q次乘法(及q-1次加法).这样,要计算出AB就需要做p×q×r次乘法.由于加法比同样数量的乘法所用时间要少得多,故不考虑加法的计算量. 看下面一个例子,计算三个矩阵连乘{A1,A2,A3}:维数分别为10*100 , 100*5 , 5*50 按此顺序计算需要的次数((A1