矩阵连乘-动归
作者:互联网
使用动态规划算法解决如下问题
问题:给定n个矩阵{A1,A2,...,An},其中Ai与Ai+1是可乘的,i=1,2,...,n-1,求矩阵相乘至少需要多少次数乘?
举例:A1 10*100,A2 100*5,A3 5*50,则A1*A2*A3至少需要7500次数乘。
#include <stdio.h> #include <stdlib.h> #include <iostream> #define MAX 50 #define inf 99999999 using namespace std; int p[MAX + 1]; //存储各个矩阵的列数以及第一个矩阵的行数(作为第0个矩阵的列数) int m[MAX][MAX]; //m[i][j]存储子问题的最优解 int s[MAX][MAX]; //s[i][j]存储子问题的最佳分割点 int n; //矩阵个数 void matrix() { int i, j, k; for (i = 0; i<n; i++) m[i][i] = 0; //最小子问题仅含有一个矩阵 ,对角线全为0 for (i = 2; i <= n; i++) for (j = 0; j<n - i + 1; j++) { m[j][j + i - 1] = inf; for (k = 0; k<i - 1; k++) { //k代表分割点 if (m[j][j + i - 1]>m[j][j + k] + m[j + k + 1][j + i - 1] + p[j] * p[j + k + 1] * p[j + i]) { m[j][j + i - 1] = m[j][j + k] + m[j + k + 1][j + i - 1] + p[j] * p[j + k + 1] * p[j + i]; s[j][j + i - 1] = k; //记录分割点 } } } } void printmatrix(int leftindex, int rightindex)//递归打印输出 { if (leftindex == rightindex) printf("A%d", leftindex); else { printf("("); printmatrix(leftindex, leftindex + s[leftindex][rightindex]); printmatrix(leftindex + s[leftindex][rightindex] + 1, rightindex); printf(")"); } } int main() { int i; printf("请输入矩阵相乘的矩阵个数"); cin >> n; printf("请依次输入矩阵的行和烈(如A*B,A=20*30,B=30*40,即输入20 30 40)\n"); for (i = 0; i < n + 1; i++) { cin>>p[i]; } matrix(); printf("矩阵连乘最小次数\t%d\n", m[0][n - 1]); printmatrix(0, n - 1); printf("\n"); system("pause"); return 0; }
标签:连乘,leftindex,动归,MAX,矩阵,int,printf,rightindex 来源: https://www.cnblogs.com/wxh-blos/p/12091945.html