問題描述:
給定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時按(a1a2)a3所需的元素乘法次數達到最少,為7500次。
輸入
測試資料有若干組,每組測試資料有2行。
每組測試資料的第1行是乙個整數n,(0輸入直到檔案結束。
輸出
對輸入中的每組測試資料,輸出2行。先在一行上輸出「case #」,其中「#」是測試資料的組號(從1開始),再在第2行上輸出計算這n個矩陣的連乘積a1a2…an時最少的總的元素乘法次數,再空一格,接著在同一行上輸出矩陣連乘的添括號形式。
注意:最外層括號應去掉。
實驗結果:
輸入樣例
10 100 5 50
50 10 40 30 5
輸出樣例
case 1
7500 (a1a2)a3
case 2
10500 a1(a2(a3a4))
程式**如下:
#include
#include
#include
#include
#include
using namespace std;
const int n=100;
int m[n][n],s[n][n];
void printanswer(int i,int j)
if(i==j)
cout<
cout<
printanswer(i,s[i][j]);
printanswer(s[i][j]+1,j);
cout<
void matrix_multi(int *p,int length)
int n=length-1;
int l,i,j,k,q=0;
//m[i][i]只有乙個矩陣,相乘次數為零,所以m[i][i]=0
for(i=1;im[i][j]=0;
for(l=2;l<=n;l++) //寬度從2到n
for(i=1;i<=n-l+1;i++)
j=i+l-1; //以i為起始位,j為末位,長度為l
m[i][j]=0x7fffffff;
for(k=i;k<=j-1;k++)
q=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
if(qm[i][j]=q;
s[i][j]=k;
void readtxt(string file)
ifstream infile;
infile.open(file.data());
assert(infile.is_open());
string s;
int i=1;
while(getline(infile,s))
int a=atoi(s.c_str());
getline(infile,s);
istringstream tmp(s);
int x[a+1];
for(int i=0;i<=a;i++)
tmp>>s;
x[i]=atoi(s.c_str());
matrix_multi(x,a+1);
cout<
cout
cout
int main()
readtxt("input.txt");
return 0;
執行結果:
思路詳解:
矩陣連乘的動態規劃演算法
矩陣鏈乘問題 輸入 共兩行 第一行 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 第二行...
矩陣連乘問題動態規劃演算法
內容 n個矩陣連乘,不滿 換律,但是滿足結合律,通過不同的加括號方式,會使得需要的乘法次數不同。用動態規劃方法計算,找出最優加括號方式,使總的乘法次數最少。下面我們考慮用動態規劃求解。預處理 將矩陣連乘積aiai 1 aj簡記為a i j 這裡i j。考察計算a i j 的最優計算次序。設這個計算次...
矩陣連乘問題(動態規劃演算法)
動態規劃演算法思想簡介 將乙個問題分解為多個子問題,這點和分治法類似,但是每個子問題不是獨立的而是相互聯絡的,所以我們在求解每個子問題的時候可能需要重複計算到其他的子問題,所以我們將計算過的子問題的解放進乙個表中,這樣就能避免了重複計算帶來的耗費,這就是動態規劃的基本思想 一般地,動態規劃思想一般用...