解答想法
共兩行第一行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-1qi**;
4. 對 k = i + 1 到 j-1
5. t = lu(i, k) + lu(k+1,j) + qi-1qk**,
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人吸收能量的一...