【SSL】2021-12-04 1596.矩阵链相乘

原题网址

由于某些原因,这个网址会进不去…

题目描述

假设我们要用标准的矩阵乘法来计算 M 1 , M 2 , M 3 M_1,M_2,M_3 M1,M2,M3三个矩阵的乘积 M 1 M 2 M 3 M_1M_2M_3 M1M2M3,这三个矩阵的维度分别是 2 × 10 , 10 × 2 , 2 × 10 2\times10,10\times2,2\times10 2×10,10×2,2×10,如果把 M 1 , M 2 M_1,M_2 M1,M2相乘,然后再与 M 3 M_3 M3相乘,那么要 2 × 10 × 2 + 2 × 2 × 10 = 80 2\times10\times2+2\times2\times10=80 2×10×2+2×2×10=80,如果代之以用 M 2 , M 3 M_2,M_3 M2,M3相乘的结果去成 M 1 M_1 M1,那么矩阵乘法的次数变成了 10 × 2 × 10 + 2 × 10 × 10 = 400 10\times2\times10+2\times10\times10=400 10×2×10+2×10×10=400,执行 M 1 ( M 2 M 3 ) M_1(M_2M_3) M1(M2M3)耗费的时间是执行乘法 ( M 1 M 2 ) M 3 (M_1M_2)M_3 (M1M2)M3 5 5 5倍。

格式

输入格式

n n n表示矩阵的个数 ( ≤ 100 ) (\le100) (100)
n + 1 n+1 n+1个数,表示矩阵 ( ≤ 100 ) (\le100) (100)

输出格式

最小的乘法次数

样例

输入样例

5
5 10 4 6 10 2

输出样例

348

解题思路

一般来说,顺序数等于这个 n n n个矩阵每一种可能的途径放置括号数的方法数。设 f ( n ) f(n) f(n)是求 n n n个知阵乘积的所有放置括号的方法数,假定要进行下面的乘法:
( A 1 A 2 . . . A k ) × ( A k + 1 A k + 2 . . . A n ) (A_1A_2...A_k)\times (A_{k+1}A_{k+2}...A_n) (A1A2...Ak)×(Ak+1Ak+2...An)
那么,对于前 k k k个矩阵有 f ( k ) f(k) f(k)对于中的每一种方法,可对余下的 f ( n − k ) f(n-k) f(nk)个矩阵放置括号的方法,总共有 f ( k ) × f ( n − k ) f(k)\times f(n-k) f(k)×f(nk)种方法。由于可以假设 k k k 1 1 1 n − 1 n-1 n1中任意值,对于 n n n个矩阵放置括号弧的所有方法数由
f ( n ) = ∑ k = 1 n − 1 f ( n ) f ( n − k ) f(n)=\sum^{n-1}_{k=1}f(n)f(n-k) f(n)=k=1n1f(n)f(nk)
给出。显然,两个矩阵相乘只有一种方法,三个矩阵相乘有两种方法。因此 f ( 2 ) = 1 , f ( 3 ) = 2 f(2)=1,f(3)=2 f(2)=1,f(3)=2,为了使递推有意义,令 f ( 1 ) = 1 f(1)=1 f(1)=1。我们可以证明
f ( n ) = C 2 n − 2 n − 1 / n f(n)=C^{n-1}_{2n-2}/n f(n)=C2n2n1/n
这个递推式就产生的CATALAN数(即卡特兰数
百度链接
1 , 1 , 2 , 5 , 14 , 42 , 132 , 429 , 1430 , 4862 , 16796... 1,1,2,5,14,42,132,429,1430,4862,16796... 1,1,2,5,14,42,132,429,1430,4862,16796...
因此, 10 10 10个矩阵相乘存在 4862 4862 4862种方法。
矩阵 A A A B B B是可乘的条件是矩阵 A A A的列数等于矩阵 B B B的行数。若 A A A是一个 p × q p\times q p×q的矩阵, B B B是一个 q × r q\times r q×r的矩阵,则其乘积 C = A B C=AB C=AB是一个 p × r p\times r p×r矩阵。在计算 C C C的标准算法中,主要计算量在三重循环,总共需要 p × q × r p\times q\times r p×q×r次数成。
3 × 2      2 × 2       3 × 2 3\times2\ \ \ \ 2\times2\ \ \ \ \ 3\times2 3×2    2×2     3×2

1       2      2       1       8       1 1\ \ \ \ \ 2\ \ \ \ 2\ \ \ \ \ 1\ \ \ \ \ 8\ \ \ \ \ 1 1     2    2     1     8     1
2       1 ∗ 3       0 = 7       3 2\ \ \ \ \ 1*3\ \ \ \ \ 0=7\ \ \ \ \ 3 2     13     0=7     3
0       1                    3       0 0\ \ \ \ \ 1\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 3\ \ \ \ \ 0 0     1                  3     0

将矩阵连乘积 A i A i + 1 … A j A_iA_{i+1}…A_j AiAi+1Aj简记为 A [ i : j ] A[i:j] A[i:j]。设最优次序在矩阵 A k A_k Ak A k + 1 A_{k+1} Ak+1A之间将矩阵链断开, 1 ≤ k < n 1\le k<n 1k<n,则完全加括号的方式为 ( ( A 1 … A k − 1 ) ( A k … A n ) ) ((A_1…A_{k-1})(A_k…A_n)) ((A1Ak1)(AkAn))。计算 F [ 1 ] [ n ] F[1][n] F[1][n]的一个最优次序所包含的计算矩阵子链 F [ 1 ] [ k − 1 ] F[1][k-1] F[1][k1] F [ k ] [ n ] F[k][n] F[k][n]的次序也是最优的。因此,矩阵连乘积计算次序问题的最优解包含着其子问题的最优解。
f [ i ] [ j ] = m i n { f [ i ] [ k − 1 ] + f [ k ] [ j ] + r i r k r j + 1 } ( i < k ≤ j ) f[i][j]=min\{f[i][k-1]+f[k][j]+r_ir_kr_{j+1}\}(i<k\le j) f[i][j]=min{f[i][k1]+f[k][j]+rirkrj+1}(i<kj)
而本问题的问题求解则为:
f [ 1 ] [ n ] = m i n { f [ 1 ] [ k − 1 ] + f [ k ] [ n ] + r 1 r k r n + 1 } f[1][n]=min\{f[1][k-1]+f[k][n]+r_1r_kr_{n+1}\} f[1][n]=min{f[1][k1]+f[k][n]+r1rkrn+1}

Code

#include<iostream>
#include<istream>
#include<ostream>
#include<sstream>
#include<fstream>
#include<iomanip>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<map>
#include<vector>
using namespace std;
const int maxn=100,inf=2147483647;
int n,m[maxn*2],f[maxn*2][maxn*2];
void init() {
    ios::sync_with_stdio(false); // 快读
    cin.tie(); // 快读
    cin>>n;
    for(int i=1;i<=n+1;i++) cin>>m[i];
}
int main() {
    init();
    for(int i=1;i<=n;i++) f[i][i]=0;
    for(int i=1;i<n;i++) {
        for(int j=1;j<=n-i;j++) {
            int k=i+j;
            f[j][k]=inf;
            for(int l=j+1;l<=k;l++) f[j][k]=min(f[j][k],f[j][l-1]+f[l][k]+m[j]*m[k+1]*m[l]);
        }
    }
    cout<<f[1][n];
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值