矩陣連乘的動態規劃演算法

2021-07-29 10:39:36 字數 1599 閱讀 2575

矩陣鏈乘問題

輸入:共兩行

第一行 n ( 1<=n<=100 ),代表矩陣個數。

第二行有 n+1 個數,分別為 a1 、 a2 ...... an+1 ( 1<=ak<=2000 ), ak 和 ak+1 代表第 k 個矩陣是個 ak x ak+1 形的。

輸出:共兩行

第一行 m ,為最優代價。注:測試用例中 m 值保證小於 2^31

第二行為最優順序。如 (a1((a2a3)a4)) ,最外層也加括號。

注意:測試用例已經保證了輸出結果唯一,所以沒有aaa的情況.

input 6

30 35 15 5 10 20 25

output

15125

((a1(a2a3))((a4a5)a6))

思路分析:

1.分析最優解的結構

設計算a[1:n](第1項到第n項連成的最優解),那麼它的子鏈a[1:k]和a[k+1:n]的次序也是最優的。

若不然,不妨設有乙個計算比a[1:k]的次序計算量更少,則用它替換原來的a[1:k],那麼a[1:n]的計算量

將比最優次序所需的計算量更少,與題設矛盾。因此最優子結構成立。

2.確定狀態及狀態方程

設問題即為狀態m[i][j]表示從第i項連乘到第j項的最優計算次數。

m[i][j] = 0 (i==j)

= min

printf("(");

printtrace(i, s[i][j]);

printtrace(s[i][j] + 1, j);

printf(")");

}int main()

for (int i = 1; i <= n; i++)

m[i][i] = 0;

for (int r = 2; r <= n; r++)//r表示對角線的序號

}} }

printf("%d\n", m[1][n]);

printtrace(1, n);

printf("\n");

return 0;

}下邊是採用遞迴和記憶化搜尋的方式dp

#include #include #include #define n 105

using namespace std;

int n;

int s[n][n], m[n][n], p[n];

void init()

int matrixchain(int i, int j)

} return m[i][j] = u;

}void printtrace(int i, int j)

printf("(");

printtrace(i, s[i][j]);

printtrace(s[i][j] + 1, j);

printf(")");

}int main()

init();

int ans = matrixchain(1, n);

printf("%d\n", ans);

printtrace(1, n);

printf("\n");

return 0;

}

矩陣連乘問題動態規劃演算法

內容 n個矩陣連乘,不滿 換律,但是滿足結合律,通過不同的加括號方式,會使得需要的乘法次數不同。用動態規劃方法計算,找出最優加括號方式,使總的乘法次數最少。下面我們考慮用動態規劃求解。預處理 將矩陣連乘積aiai 1 aj簡記為a i j 這裡i j。考察計算a i j 的最優計算次序。設這個計算次...

矩陣連乘問題(動態規劃演算法)

動態規劃演算法思想簡介 將乙個問題分解為多個子問題,這點和分治法類似,但是每個子問題不是獨立的而是相互聯絡的,所以我們在求解每個子問題的時候可能需要重複計算到其他的子問題,所以我們將計算過的子問題的解放進乙個表中,這樣就能避免了重複計算帶來的耗費,這就是動態規劃的基本思想 一般地,動態規劃思想一般用...

c 矩陣連乘的動態規劃演算法並輸出 矩陣連乘

問題描述 給定n個矩陣a1,a2,an,其中,ai與aj 1是可乘的,i 1,2,n l。你的任務是要確定矩陣連乘的運算次序,使計算這n個矩陣的連乘積a1a2 an時總的元素乘法次數達到最少。例如 3個矩陣a1,a2,a3,階分別為10 100 100 5 5 50,計算連乘積a1a2a3時按 a1...