标签:
矩阵最少乘法
题意:
给你2个矩阵A、B,我们使用标准的矩阵相乘定义C=AB如下:
A阵列中栏(column)的数目一定要等于B阵列中列(row)的数目才可以做此2阵列的相乘。若我们以rows(A),columns(A)分别代表A阵列中列及栏的数目,要计算C阵列共需要的乘法的数目为:rows(A)*columns(B)*columns(A)。例如:A阵列是一个10x20的矩阵,B阵列是个20x15的矩阵,那么要算出C阵列需要做10*15*20,也就是3000次乘法。
要计算超过2个以上的矩阵相乘就得决定要用怎样的顺序来做。例如:X、Y、Z都是矩阵,要计算XYZ的话可以有2种选择:(XY)Z 或者X(YZ)。假设X是5x10的阵列,Y是10x20的阵列,Z是20x35的阵列,那个不同的运算顺序所需的乘法数会有不同:
(XY)Z
X(YZ)
很明显的,我们可以知道计算(XY)Z会使用较少次的乘法。
这个问题是:给你一些矩阵,你要写一个程式来决定该如何相乘的顺序,使得用到乘法的次数会最少。
思路:最优矩阵链乘问题,典型的动态规划题目。
#include<stdio.h> #define m 1000 #define inf 0x3f3f3f3f int dp[m][m],s[m][m],p[m],n; void print(int i,int j)//递归输出所有的结果 { if(i==j) printf("A%d",i); //输出是第几个数据 else { printf("("); print(i,s[i][j]);//递归下一个数据 printf(" x "); print(s[i][j]+1,j); printf(")"); } } void work() { int i,j,k,l,t; for(i=1; i<=n; i++) dp[i][i]=0;//首先初始化为0 for(l=2; l<=n; l++) for(i=1; i<=n-l+1; i++) { j=i+l-1; //判断i和j之间的最优解 dp[i][j]=inf; for(k=i; k<=j-1; k++) { t=dp[i][k]+dp[k+1][j]+p[i-1]*p[k]*p[j]; if(t<dp[i][j]) { dp[i][j]=t; //保持最优解 s[i][j]=k; //记录需要加括号的地方 } } } print(1,n); //输出i和j之间的最优解 puts(""); } int main() { int c=1,i; while(scanf("%d",&n)&&n) { for(i=1; i<=n; i++) scanf("%d%d",&p[i-1],&p[i]);//输入数据 printf("Case %d: ",c++); work(); } return 0; }
AYITACM2016省赛第三周I - Optimal Array Multiplication Sequence(dp)
标签:
原文地址:http://blog.csdn.net/linyuxilu/article/details/51334944