動態規劃之矩陣連乘問題
阿新 • • 發佈:2018-12-24
問題描述
給定n個矩陣:A1,A2,…,An,其中Ai與Ai+1是可乘的,i=1,2…,n-1。確定計算矩陣連乘積的計算次序,使得依此次序計算矩陣連乘積需要的數乘次數最少。輸入資料為矩陣個數和每個矩陣規模,輸出結果為計算矩陣連乘積的計算次序和最少數乘次數。
解題思路與演算法思想
- 仍然是先使用動態規劃的核心思想:分治
- 我們可以將任何一個括號視為一個斷點
這樣一個完整式子就變成了很多個不同部分求和再相加
那麼我們只需要找出不同和式子和求和方式即可
程式模型的建立
對於從第i個式子到第j個式子 一共有j-i個種斷點選擇方式 對於這些不同的觀點選擇方式,我們要求出最小值,之後通過遞迴呼叫即可
資料結構的選用
- 利用pair來儲存一個矩陣的資訊
- 利用vector來儲存全部的pair資訊
程式設計流程
- 輸入資訊
- 寫出遞迴呼叫函式
- 進行遞迴呼叫
程式設計偽碼演算法
int tem ;
for(int k = i ; k<j ;k++)
{
tem = get_min(i,k)+get_min(k+1,j)+a[i].first*a[k].second*a[j].second ;
if(tem<sum)
{
sum = tem ;
}
}
源程式編碼清單
#include<iostream> #include<vector> #include<utility> using namespace std ; vector< pair<int,int> > a ; int get_min(int i ,int j) ; int main(void) { int n ; scanf("%d",&n) ; int tem1 ; int tem2 ; for(int i = 0 ; i<n ;i++) { scanf("%d",&tem1) ; scanf("%d",&tem2) ; pair<int ,int>tema = make_pair(tem1,tem2) ; a.push_back(tema) ; } printf("%d",get_min(0,n-1)) ; } int get_min(int i ,int j) { int sum = 0x7fffffff ; if(i==j) { return 0 ; } else { int tem ; for(int k = i ; k<j ;k++) { tem = get_min(i,k)+get_min(k+1,j)+a[i].first*a[k].second*a[j].second ; if(tem<sum) { sum = tem ; } } } return sum ; }
程式輸入、輸出
輸入:
6
30 35
35 15
15 5
5 10
10 20
20 25
輸出:
15125
輸入輸出檔案,或程式執行結果截圖
時間與空間複雜度分析
時間複雜度:n^2
空間複雜度:n^2
程式使用說明
總結與完善