1. 程式人生 > >動態規劃之矩陣連乘問題

動態規劃之矩陣連乘問題

 問題描述
給定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

 程式使用說明

 總結與完善