题目
[外链图片转存失败(img-JEblFzHk-1562483192850)(http://10.156.17.250/JudgeOnline/image/1596.gif)]
输入
n表示矩阵的个数(<=100)
n+1个数,表示矩阵(<=100)
输出
最小的乘法次数
输入样例
5
5 10 4 6 10 2
输出样例
348
解题思路
其实方法和石子合并差不多,但是前k个矩阵有f(k)对于中的每一种方法,可对余下的f(n-k)个矩阵放置括号的方法,所以总共有f(k)*f(n-k)种方法,则可以推出公式:
f
[
i
]
[
j
]
=
m
i
n
(
f
[
i
]
[
j
]
,
f
[
i
]
[
k
−
1
]
+
f
[
k
]
[
j
]
+
a
[
i
]
∗
a
[
k
]
∗
a
[
j
+
1
]
)
;
f[i][j]=min(f[i][j],f[i][k-1]+f[k][j]+a[i]*a[k]*a[j+1]);
f[i][j]=min(f[i][j],f[i][k−1]+f[k][j]+a[i]∗a[k]∗a[j+1]);
因为矩阵的k种方法只是分界线,所以是要f[i][k-1]前的矩阵
因此,计算F[1][n]的一个最优次序所包含的计算矩阵子链F[1][k-1]和F[k][n]的次序也是最优的
所以矩阵连乘积计算次序问题的最优解包含着其子问题的最优解.
程序如下
#include<iostream>
#include<cstdio>
using namespace std;
int n,a[105],f[105][105],h;
int main()
{
scanf("%d",&n);
memset(f,127/3,sizeof(f));
for(int i=1;i<=n+1;i++)
{
scanf("%d",&a[i]);
f[i][i]=0;
}
for(int len=2;len<=n;len++)//矩阵的个数范围
{
for(int i=1;i<=n-len+1;i++)
{
int j=i+len-1;
for(int k=i+1;k<=j;k++)//k是在i到j之间的一个分界点
{
f[i][j]=min(f[i][j],f[i][k-1]+f[k][j]+a[i]*a[k]*a[j+1]);
}
}
}
printf("%d",f[1][n]);
return 0;
}