矩陣連乘問題 區間動規

2021-10-18 14:29:49 字數 2575 閱讀 9886

解答想法

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

第二行有n+1個數,分別為q(0), q(1), ..., q(n) (1<=q(k)<=2000), 代表第 k 個矩陣是q(k-1)xq(k)維的。

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

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

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

6

30 35 15 5 10 20 25

15125

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

1

1 1

0

(a1)

#include

#include

using

namespace std;

#define max 2010

int ans[max]

[max]=;

//儲存矩陣鏈 a[i..j]的最小代價

int divide[max]

[max]=;

//記錄最小代價ans[i,j]對應的分割點

/* 計算n元矩陣鏈p的最優代價

* 動態規劃的每一步結果儲存在 ans與 divide中 */

void

matrixchainorder

(int p,

int n)}}

}}//根據divide陣列,輸出a[i..j]的最優情況

void

printdivide

(int i,

int j)

else

}int

main()

else

cout << endl;

return0;

}

#include

#include

using

namespace std;

#define max 2010

int ans[max]

[max]=;

// 儲存矩陣鏈 a[i..j]的最小代價

int divide[max]

[max]=;

// 記錄最小代價ans[i,j]對應的分割點

/* 計算n元矩陣鏈p的最優代價

* 動態規劃的每一步結果儲存在 ans與 divide中 */

void

matrixchainorder

(int p,

int n)

//矩陣鏈長度為2到n

for(

int l =

2; l <= n; l++)}

}}}/* 根據divide陣列,輸出a[i..j]的最優情況 */

還有老師介紹的另一種方法,自頂而下的一種方法,更加適合於只用計算部分即可的題

1. 對所有i,j, m[i,j]=0

2. lu(1,n) //lookup

lu(i,j)

1. 若 m[i,j]>0, 返回 m[i,j]

2. 若 i = = j, 返回0

3. s[i,j] = i; m[i,j] = lu(i,i) + lu(i+1,j) + qi-1qi**;

4. 對 k = i + 1 到 j-1

5. t = lu(i, k) + lu(k+1,j) + qi-1qk**,

6. 若m[i,j]>t, 則m[i,j]=t; s[i,j]=k;

7. 返回m[i][j]

動態規劃方法採用自底向上

備忘錄方法採用自頂向下

都能解決重疊子問題

當所有子問題都至少要求解一次時,用動態規劃方法比較好

當部分子子問題不用求解時,用備忘錄方法比較好

矩陣連乘問題宜用動態規劃

石子合併(區間型動規)

在乙個圓形操場的四周擺放n堆石子 n 500 現要將石子有次序地合併成一堆。規定每次只能選相鄰的兩堆合併成新的一堆,並將新的一堆的石子數,記為該次合併的得分。編一程式,由檔案讀入堆數n及每堆的石子數 選擇一種合併石子的方案,使得做n 1次合併,得分的總和最小 選擇一種合併石子的方案,使得做n 1次合...

區間型別動規 乘積最大

訓練題 乘積最大 description 今年是國際數學聯盟確定的 2000 世界數學年 又恰逢我國著名數學家華羅庚先生誕辰90周年。在華羅庚先生的家鄉江蘇金壇,組織了一場別開生面的數學智力競賽的活動,你的乙個好朋友xz也有幸得以參加。活動中,主持人給所有參加活動的選手出了這樣一道題目 設有乙個長度...

區間型別動規 能量項鍊

能量項鍊 description 在mars星球上,每個mars人都隨身佩帶著一串能量項鍊。在項鍊上有n顆能量珠。能量珠是一顆有頭標記與尾標記的珠子,這些標記對應著某個正整數。並且,對於相鄰的兩顆珠子,前一顆珠子的尾標記一定等於後一顆珠子的頭標記。因為只有這樣,通過吸盤 吸盤是mars人吸收能量的一...