矩陣鏈相乘 DP

2021-09-03 02:58:07 字數 1427 閱讀 8888

n表示矩陣的個數(<=100)

n+1個數,表示矩陣(<=100)

> output

最小的乘法次數

> sample input

55 10 4 6 10 2

> sample output

348> 解題思路

按照題意,這幾個數只能結合相乘,不能交換相乘,也就是不能打亂數的排列順序(因為這個矩陣鏈的乘法hin是奇怪,一交換答案就不一樣了)。

然後老師讓我們算了一下它有多少種乘法的方式,數字十分之巨大,為catalan數,所以不能用遞迴,這時dp就出現了。

迴圈中,d為長度,i、j為邊界(i起始,j結束),k為劃分。

接下來,由於假設給出的數為5 10 4 6 10 2們,那麼就有5個矩陣5·10,10·4,4·6,6·10,10·2;

5·10與10·4的矩陣可以合成乙個5·4大小的矩陣,乘法的次數為5·10·4,

狀態轉移方程:

f[i][j]=min(f[i][j],f[i][k-1]+f[k][j]+a[i]*a[k]*a[j+1])

也就是把i到j分為兩段,假如數5 10 4 6(10),k在數10上,就表示把這4個矩陣劃分成兩段:5·10和10·4 4·6 6·10。 按照我神奇地理解,就是f[i][j]表示數從i到j,矩陣就是從i到j中每乙個數乘後乙個數所組成的矩陣

解釋一下狀態轉移方程:就是分為兩段,把第一段內的次數和第二段內的次數相加,再加上兩段最後組成乙個矩陣的次數。f[i][k-1]在上面已經解釋過,為了組成i*(i+1),…,(k-1)*k;a[i]*a[k]*a[j+1]中(j+1)是因為每一串數中的最後乙個數還要跟這一串數後面的乙個數組成乙個矩陣。

> **

#include

#include

using namespace std;

const int inf=

1000000

;int n,a[

105]

,f[105][

105]

;int main()

for(int d=

2;d<=n;d++

)for

(int i=

1;i<=n-d+

1;i++

)printf

("%d"

,f[1

][n]);

return0;

}

DP 矩陣鏈相乘

假設我們要用標準的矩陣乘法來計算m1,m2,m3三個矩陣的成績m1m2m3,這三個矩陣的維數分別是210,102,210,如果把m1,m2相乘,然後再與m3相乘,那麼要乘2102 2210 80次,如果代之以用m2,m3相乘的結果去乘m1,那麼乘法的次數變成了10210 210 10 400,執行m...

矩陣鏈相乘Matchain

演算法設計技巧與分析 動態規劃僅供自己學習.輸入 n個矩陣的鏈的維數對應於正整數陣列r 1,2,n 是n個矩陣的行數,r n 1 是mn的列數 輸出 n個矩陣相乘的數量乘法的最小次數 例7.4 m1 5 10,m2 1 4,m3 4 6,m4 6 10,m5 10 2 c 1,1 0 c 1,2 2...

矩陣鏈相乘問題

矩陣的乘法定義如下 設a是m p的矩陣,b是p n的矩陣,則a與b的乘積為m n的矩陣,記作c ab,其中,矩陣c中的第i行第j列元素cij可以表示為 當多個矩陣相乘時,採用不同的計算順序所需的乘法次數不相同。例如,a是50 10的矩陣,b是10 20的矩陣,c是20 5的矩陣,計算abc有兩種方式...