1)問題引導c++
一個demo算法
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 int main() 6 { 7 int array1[3][4]={{1,1,1,2},{2,2,3,3},{3,4,4,4}}; 8 int array2[4][3]={{1,1,1},{2,2,2},{3,3,3},{4,4,4}}; 9 int array3[3][3]; 10 for(int i=0;i<3;i++){ 11 for(int j=0;j<3;j++) 12 { 13 for(int k=0;k<4;k++) 14 { 15 array3[i][j]=array1[i][k]*array2[k][j]; 16 } 17 } 18 } 19 for(int i=0;i<3;i++){ 20 for(int j=0;j<3;j++) 21 { 22 cout << array3[i][j] << " "; 23 } 24 cout << endl; 25 } 26 27 return 0; 28 }
從上面咱們能夠知道不一樣的結合方式,矩陣計算的次序數不同,那麼如何求這個最小次序數的劃分,即如何結合。這就是矩陣連乘問題spa
使用動態規劃能夠解決3d
以下圖,若是咱們使用遞歸,則會產生大量的重複計算,複雜度過高,固然使用備忘錄下降複雜度。不過更好的是使用遞推code
遞推算法分析以下:blog
1 #include<bits/stdc++.h> 2 using namespace std; 3 void matrixChain(int n,int p[],int m[][100],int s[][100])//遞推 4 { 5 for(int i=1;i<=n;i++){//對角線先爲0 6 m[i][i]=0; 7 } 8 for(int r=2;r<=n;r++){//一共n-1個對角線 9 for(int i=1;i<=n-r+1;i++){//第i行 10 int j=i+r-1;//在該行的對角線上的點對應的j值 11 m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j];//初始化此時在i處取得最優解 12 s[i][j]=i; 13 for(int k=i+1;k<j;k++){//若是有更小的則被替換 14 int t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j]; 15 if(t<m[i][j]) 16 { 17 m[i][j]=t; 18 s[i][j]=k; 19 } 20 } 21 } 22 } 23 } 24 void print_optimal_parents(int s[100][100],int i,int j)//打印劃分的結果 25 { 26 if( i == j) 27 cout<<"A"<<i; 28 else 29 { 30 cout<<"("; 31 print_optimal_parents(s,i,s[i][j]); 32 print_optimal_parents(s,s[i][j]+1,j); 33 cout<<")"; 34 } 35 36 } 37 int main() 38 { 39 int p[1000];//每一個矩陣的行數和最後一個的列數 40 int m[100][100];//存儲最優子結構 41 int s[100][100];//存儲當前結構的最優斷點 42 memset(p,0,sizeof(p)); 43 memset(m,0,sizeof(m)); 44 memset(s,0,sizeof(s)); 45 cout << "請輸入矩陣的個數"<< endl; 46 int n; 47 cin >> n; 48 cout << "請依次輸入每一個矩陣的行數和最後一個矩陣的列數"<< endl; 49 for(int i=0;i<=n;i++){ 50 cin >> p[i]; 51 } 52 matrixChain(n,p,m,s); 53 cout <<"這些矩陣相乘的最少次數是"<<m[1][n]<<endl; 54 55 cout<<"結果是:"<<endl; 56 print_optimal_parents(s,1,n); 57 return 0; 58 }