矩阵连乘问题解法有穷举法、动态规划法和备忘录法。矩阵连乘问题要解决最优相乘次序问题和构造最优解。
备忘录法和动态规划都使用一个数组m[i][j]来存储第i到j矩阵相乘的最少相乘次数,动态规划中r表示链长,r为1时候m为0,所以从2到n,r-1=j-i;s[i][j]用于构造最优解,记下每一个斜线的最少相乘次数的位置,k是i到j的最优划分位置的变量。
这里以ACM-矩阵连乘动态规划求最优值和ACM-矩阵连乘备忘录求最优值为例。
//备忘录
#include<stdio.h>
#include<math.h>
#include<string.h>
int n,p[100],m[100][100];
int lookupChain(int i,int j){
if(m[i][j]>0)
return m[i][j];
if(i==j)
return 0;
int u=lookupChain(i,i)+lookupChain(i+1,j)+p[i-1]*p[i]*p[j];//初始化最小值,在i后面分割
for(int k=i+1;k<j;k++)
{
int f=lookupChain(i,k)+lookupChain(k+1,j)+p[i-1]*p[k]*p[j];
if(f<u)
u=f;
}
m[i][j]=u;
return u;
}
int main(void){
while (scanf("%d",&n)!=EOF)
{
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
m[i][j]=0;
}
for (int i = 0; i < n; i++)
{
scanf("%d",&p[i]);
}
int t = lookupChain(1,n-1);
printf("%d\n",t);
}
return 0;
}
//动态规划
#include<stdio.h>
#include<math.h>
#include<string.h>
int p[100],m[100][100],s[100][100];
void matrixchain(int n)
{
int i,j,r,k;
for ( i = 0; i <=n; i++)
for ( j = 0; j <=n; j++)
{
m[i][j]=0;
s[i][j]=0;
}
for ( r = 2; r <=n; r++)
for ( i = 1; i <=n-r+1; i++)
{
j=i+r-1;
m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j];
s[i][j]=i;
for ( 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;
}
}
}
}
int main(void){
int n;
while (scanf("%d",&n)!=EOF)
{
for (int i = 0; i <n; i++)
{
scanf("%d",&p[i]);
}
matrixchain(n-1);
printf("%d\n",m[1][n-1]);
}
return 0;
}