编程实现矩阵连乘问题的求解
思路:
由矩阵相乘的计算方式可知,每次相乘增加的数乘次数之和,相乘矩阵的维数有关;
状态分析:
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]表示从第
i
i
i个矩阵到第
j
j
j个矩阵相乘的最少数乘次数
状态计算:
每次从
[
i
,
j
)
[i,j)
[i,j) 中寻找一个
k
k
k,计算
[
i
,
k
]
[i,k]
[i,k]与
[
k
+
1
,
j
]
[k+1,j]
[k+1,j]两部分矩阵相乘的结果,取最小值
状态转移方程:
d
p
[
i
]
[
j
]
=
m
i
n
(
d
p
[
i
]
[
k
]
+
d
p
[
k
?
1
]
[
j
]
+
c
o
l
[
i
]
r
o
w
[
k
]
r
o
w
[
j
]
)
dp[i][j] = min(dp[i][k] + dp[k-1][j] + col[i]row[k]row[j])
dp[i][j]=min(dp[i][k]+dp[k?1][j]+col[i]row[k]row[j]) (
i
+
1
<
=
k
<
j
i + 1<= k < j
i+1<=k<j)
代码:
#include<stdio.h>
int n , q[110] , s[110], dp[110][110];
int main()
{
scanf("%d",&n);
for(int i = 1 ; i <= n ; i ++) scanf("%d%d",&q[i],&s[i]);
for(int i = n ; i >= 1 ; i --)
for(int j = i + 1 ; j <= n ; j ++)
for(int k = i ; k < j ; k ++)
{ int tt = dp[i][k]+dp[k+1][j] + q[i]*s[k]*s[j];
if(!dp[i][j] || dp[i][j] > tt) dp[i][j] = tt ;
}
printf("%d\n",dp[1][n]);
return 0;
}
|