给定n个矩阵{A1,A2,...,An},其中Ai与Ai+1是可乘 的,i=1,2...,n-1。如何确定计算矩阵连乘积的计算次序,使得依此次序 计算矩阵连乘积需要的数乘次数最少。
输入数据:共m+1行;第一行为测试数据的组数m;以后每行n+1个正 整数,表示n个矩阵的行列值。
输出:最少次数及连乘的计算次序。
样例输入:
1
5,10,4,6,10,2
样例输出:
348
(A1(A2(A3(A4A5))))
动态规划:
#include<iostream>
#include<string.h>
using namespace std;
int a[1000];
int s[1000][1000];
int Matrix(int n){
int **m = new int *[n];
for(int i = 0; i < n; i++){
m[i] = new int [n];
memset(m[i], 0, sizeof(int) * n); //m[i][i]同时设置为0
}
//跨度
for(int i = 1; i < n - 1; i++){
//第j行
for(int j = 1; j < n; j++){
if(j + i >= n) break;
//每个合法元素为m[j][j + i]
int min = 0, temp = 0;
min = m[j + 1][j + i] + a[j - 1] * a[j] * a[j + i];
s[j][j + i] = j;
for(int k = j + 1; k < j + i; k++){
temp = m[j][k] + m[k + 1][j + i] + a[j - 1] * a[k] * a[j + i];
if(temp < min){
min = temp;
s[j][j + i] = k;
}
}
m[j][j + i] = min;
}
}
return m[1][n - 1];
}
void TraceBack(int i, int j){
if(i == j){
cout << 'A' << i;
return ;
}
cout << "(";
TraceBack(i, s[i][j]);
TraceBack(s[i][j] + 1, j);
cout << ")";
}
int main(){
char ch = ' ';
int M;
cin >> M;
getchar();
for(int i = 0; i < M; i++){
int n = 0, times = 0;
memset(a, 0, sizeof(int) * 1000);
for(int i = 0; i < 1000; i++) memset(s[i], 0, sizeof(int) * 1000);
for(int i = 0; ch != '\n'; i++, n++){
scanf("%d", &a[i]);
ch = getchar();
}
times = Matrix(n);
cout << times << endl;
TraceBack(1, n - 1);
ch = ' ';
}
return 0;
}