矩阵链连乘问题

给定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;
}
发布了135 篇原创文章 · 获赞 23 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/LightInDarkness/article/details/86494585