標籤:
題目描述
零崎有很多朋友,其中有一個叫jhljx。
jhljx大家很熟悉了,他數學不好也是出了名的,大家都懂。
現在jhljx遇到了矩陣乘法,他當時就懵了。數都數不清的他,矩陣乘法怎麼可能會算的清楚呢?雖然零崎覺得還不如讓你們來算,不過好歹也要給jhljx個面子,給她留下一個證明自己數學實力的機會。為了減小jhljx的計算量,讓他趕快算出不正確答案來(估計他算上幾遍都不一定能出一個正確答案),零崎請你們協助jhljx。
輸入
多組輸入資料。
每組資料以N開始,表示矩陣鏈的長度。接下來一行N+1個數表示矩陣的行/列數。
1<=N<=300
輸出
對於每組範例,輸出一行最少運算次數的方案,每兩個矩陣相乘都用“()”括起來,詳見範例
如果存在多種解決方案,最終輸出結果選取先計算左邊的矩陣,詳見Hint
輸入範例
310 30 5 60310 20 5 4
輸出範例
((A1A2)A3)((A1A2)A3)
Hint
對於輸入的第二組資料,
如果計算順序為((A1A2)A3),結果為10×20×5 + 10×5×4= 1200,
如果計算順序為A1(A2A3), 結果為20×5×4 + 10×20×4 = 1200
那麼輸出結果選取第一個
題目來源:http://biancheng.love/contest/17/problem/D/index
題目注意事項:如果存在多種解決方案,最終輸出結果選取先計算左邊的矩陣
下面給出實現代碼:
1 #include <bits/stdc++.h> 2 #define max_size 400 3 #define INF 100000000 4 long long s[max_size][max_size];//儲存構造最優解資訊 5 long long p[max_size];//矩陣規模的記錄 6 long long m[max_size][max_size];//記錄最優值 7 8 void matrix_chain_order(int n) 9 {10 for(int i=1;i<=n;i++)11 {12 m[i][i]=0;//初始化最優值(起始於1,結束於n)13 }14 for(int l=2;l<=n;l++)//l表示矩陣的長度15 {16 for(int i=1;i<=n-l+1;i++)17 {18 int j=i+l-1;19 m[i][j]=INF;20 s[i][j]=0;21 for(int k=j-1;k>=i;k--)//解決方案優先選取先左邊的矩陣22 {23 int q=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];24 if(q<m[i][j])25 {26 m[i][j]=q;27 s[i][j]=k;28 }29 }30 }31 }32 }33 34 void print_optimal_parents(int i,int j)//列印最優解的結果35 {36 if(i==j)37 printf("A%d",i);38 else39 {40 printf("(");41 print_optimal_parents(i,s[i][j]);42 print_optimal_parents(s[i][j]+1,j);43 printf(")");44 }45 }46 47 int main()48 {49 int n;50 while(~scanf("%d",&n))51 {52 memset(p,0,sizeof(p));53 for(int i=0;i<=n;i++)54 {55 scanf("%lld",&p[i]);56 }57 matrix_chain_order(n);58 print_optimal_parents(1,n);59 printf("\n");60 }61 }
對實現過程的詳細解答請見http://www.cnblogs.com/Anker/archive/2013/03/10/2952475.html
矩陣鏈相乘執行個體