NYOJ 1409 快速計算【矩陣連乘】

神探小小迪發表於2018-09-19

題目描述:

給定n個矩陣{A1,A2A3,…,An},其中,Ai 和Ai+1(i=1,2,…,n−1)是可乘的。矩陣乘法如圖4-40所示。用加括號的方法表示矩陣連乘的次序,不同的計算次序計算量(乘法次數)是不同的,找出一種加括號的方法,使得矩陣連乘的計算量最小。

例如:

A1是M5×10的矩陣;

A2是M10×100的矩陣;

A3是M100×2的矩陣。

那麼有兩種加括號的方法:

(1)(A1 A2)A3;

(2)A1(A2 A3)。

第1種加括號方法運算量:5×10×100+5×100×2=6000。

第2種加括號方法運算量:10×100×2+5×10×2=2100。

不同的加括號辦法,矩陣乘法的運算次數可能有巨大的差別!

輸入描述:

第一行是一個整型數m(m<100)表示共有m組測試資料。
每組測試資料的第一行是一個整數n(0<n<100)表示矩陣的個數。
第2行共n+1個整數pi((0<pi<100)),是每個矩陣的行數和最後一個矩陣的列數。</span>

輸出描述:

對於每一組輸入,輸出矩陣連乘的最少乘法次數。
每組的輸出佔一行。</span>

樣例輸入:

複製

2
5
3 5 10 8 2 4
8
4 8 12 7 9 30 4 65 52

樣例輸出:

314
16516

題解:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define INF 0x3f
using namespace std;
const int maxn = 1005;
int dp[maxn][maxn];
int k, m, n;
int p[maxn];

int main()
{
    cin >> m;
    while(m--) {
        cin >> n;
        for(int i = 0; i <= n; i++)
            cin >> p[i];
        memset(dp, 0, sizeof dp);
        for(int x = 2; x <= n; x++) {
            for(int i = 1; i <= n-x+1; i++) {
                int j = i+x-1;
                dp[i][j] = dp[i+1][j] + p[i-1]*p[i]*p[j];
                for(int l = i; l < j; l++) {
                    dp[i][j] = min(dp[i][l]+dp[l+1][j]+p[i-1]*p[l]*p[j], dp[i][j]);
                }
            }
        }
        cout << dp[1][n] <<endl;
    }
    return 0;
}

 

相關文章