题目描述
实现矩阵连乘算法。输入n个矩阵的维度(n+1个数, n>2),输出矩阵连乘的最小数乘次数以及连乘次序,即矩阵加括号的方式,如: (A1((A2A3)A4))。
提交格式
实现void solve(int n,int p[],int out[])函数。
参数n为矩阵个数,p为关于矩阵维数的n+1个数,矩阵Ai的维数为(p[i-1],p[i]),out[0]为最小数乘次数MOD1000000007,out[i]为输出的连乘次序(i>0)。2<n<=500,2<p[i]<=500。
输出连乘次序时,请将(替换为-1、)替换为-2,矩阵Ai替换为i,输出到out数组中。
请不要printf输出任何内容。
输出样例
输入样例:
n=5,p={10,5,2,8,6,3}
输出样例:
out={292,-1,-1,1,2,-2,-1,-1,3,4,-2,5,-2,-2}
代码
#include<iostream>
using namespace std;
long long m[501][501];
int s[501][501];
int locate=1;
void MixChain(int p[],int n,int s[][501], long long m[][501],int out[])
{
for(int i = 1; i <= n; i++)
{
m[i][i] = 0;}
for (int r = 1; r <= n - 1; r++)
{
for (int i = 1; i <= n - r; i++)
{
int j = i + r;
m[i][j] = m[i + 1][j] + p[i - 1] * p[i] * p[j];
s[i][j] = i;
for (int k = i + 1; k < j; k++)
{
long long temp = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j];
if (temp < m[i][j])
{
m[i][j] = temp;
s[i][j] = k;
}
}
}
}
out[0] = m[1][n]% 1000000007;
}
void ADDChain(int i, int j, int out[],int s[][501]) {
if (i == j)
{ out[locate++] = i;
return;
}
out[locate++] = -1;
ADDChain(i, s[i][j], out,s);
ADDChain(s[i][j] + 1, j, out,s);
out[locate++] = -2;
}
void solve(int n, int p[], int out[]) {
MixChain(p, n, s, m, out);
ADDChain(1, n, out,s);
}