其他分享
首页 > 其他分享> > 矩阵连乘-动归

矩阵连乘-动归

作者:互联网

使用动态规划算法解决如下问题

问题:给定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