矩阵连乘问题(贪心)

Posted ALLap

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了矩阵连乘问题(贪心)相关的知识,希望对你有一定的参考价值。

矩阵的乘积:一个i行j列的矩阵和一个j行k列的矩阵相乘,计算次数为i*j*k

那么问题来了:给定n个可相乘的矩阵,怎么相乘才能是计算次数最少呢?

输入:

  多组输入数据。

  每组数据以N开始,表示矩阵链的长度。接下来一行N+1个数表示矩阵的行/列数。

  1<=N<=300

输出:

  对于每组样例,输出一行最少运算次数的方案,每两个矩阵相乘都用“()”括起来,详见样例

  如果存在多种解决方案,最终输出结果选取先计算左边的矩阵,详见Hint

输入样例:

3

10 30 5 60

3

10 20 5 40

输出样例:

((A1A2)A3)

((A1A2)A3)

解法:

  用p[i]表示第i个矩阵的列/p[i-1]表示第i个矩阵的行,关键在于对一段长矩阵链中找到一个分割点。并用s[ ][ ]记录分割点,便于最后的输出。

  状态:m[i][j]表示第i个矩阵到第j个矩阵乘积的最小值

  状态转移:m[i][j]=min{m[i][k-1]+m[k][j]+p[i-1]*p[k-1]p[j](i+1<=k<=j)}//这里把第k个矩阵归为后半部分,同时由于优先计算左边的,所以我们从右边往左边找断点。

 1 #include<iostream>
 2 using namespace std;
 3 const int num=302;
 4 int matrix_chain(int p[], int n, int m[num][num], int s[num][num])
 5 {
 6     int i,j,r,k;
 7     for (r = 2; r <= n; r++) //r为连乘矩阵的个数
 8     {
 9         for (i = 1; i <= n-r+1; i++)
10         {
11             j = i + r -1; 
12             m[i][j] = 9999999;
13             for (k = j; k >= i+1; k--)//从右边开始找断点
14             {
15                 int tmp = m[i][k-1] + m[k][j] + p[i-1]*p[k-1]*p[j];
16                 if (tmp < m[i][j])
17                 {
18                     m[i][j] = tmp;
19                     s[i][j] = k;
20                 }
21             }
22         }
23     }
24     return m[1][n];
25 }
26 
27 void print_chain(int i, int j, int a[],int s[num][num])
28 {    //递归的方式来把最小乘数的表达式输出
29     if (i == j)
30     {
31         printf("A%d",a[i]);
32     }
33     else
34     {
35         printf("(");
36         print_chain(i,s[i][j]-1,a,s);
37         print_chain(s[i][j],j,a,s);
38         printf(")");
39     }
40 }
41 
42 int main()
43 {
44     int n;
45     int min_num;
46     int p[num]={0};
47     int a[num]={0};
48     int m[num][num]={0}, s[num][num]={0};
49     while(cin>>n)
50     {
51 
52             for(int t=0;t<=n;t++)
53                 cin>>p[t];
54             for(int k=1;k<=n;k++)
55                 a[k]=k;//用于给矩阵标号便于输出
56             min_num = matrix_chain(p,n,m,s);
57             print_chain(1,n,a,s);
58             cout<<"\n";
59     }
60     system("pause");
61     return 0;
62 }

 

以上是关于矩阵连乘问题(贪心)的主要内容,如果未能解决你的问题,请参考以下文章

矩阵连乘问题

矩阵连乘问题(动态规划算法)

动态规划:矩阵连乘问题

矩阵连乘问题

矩阵乘法——连乘中的数学问题

动态规划-矩阵连乘问题