最優矩陣連乘問題 區間DP

最優矩陣連乘積

Accepted: 10 Total Submit: 18
Time Limit: 1000ms Memony Limit: 32768KBios

Description

在科學計算中常常要計算矩陣的乘積。矩陣A和B可乘的條件是矩陣A的列數等於矩陣B的行數。若A是一個p×q的矩陣,B是一個q×r的矩陣,則其乘積C=AB是一個p×r的矩陣。其標準計算公式爲:ide

最優矩陣連乘

由該公式知計算C=AB總共須要pqr次的數乘。spa

爲了說明在計算矩陣連乘積時加括號方式對整個計算量的影響,咱們來看一個計算3個矩陣{A1,A2,A3}的連乘積的例子。設這3個矩陣的維數分別爲10×100,100×5和5×50。若按第一種加括號方式((A1A2)A3)來計算,總共須要10×100×5+10×5×50=7500次的數乘。若按第二種加括號方式(A1(A2A3))來計算,則須要的數乘次數爲100×5×50+10×100×50=75000。第二種加括號方式的計算量是第一種加括號方式的計算量的10倍。因而可知,在計算矩陣連乘積時,加括號方式,即計算次序對計算量有很大影響。code

因而,人們天然會提出矩陣連乘積的最優計算次序問題,即對於給定的相繼n個矩陣{A1,A2,…,An}(其中Ai的維數爲pi-1×pi ,i=1,2,…,n),如何肯定計算矩陣連乘積A1A2…An的一個計算次序(徹底加括號方式),使得依這次序計算矩陣連乘積須要的數乘次數最少。blog

Input

有若干種案例,每種兩行,第一行是一個非負整數n表示矩陣的個數,n=0表示結束。接着有n行,每行兩個正整數,表示矩陣的維數。token

Ouput
對應輸出最小的乘法次數。ip

Sample Input

3ci

10 100get

100 5string

5 50

6

30 35

35 15

15 5

5 10

10 20

20 25

0

Sample Output

7500

15125

 

#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
#define ll long long
using namespace std;
int dp[105][105],p[105];//dp[i][j]表示從第i個矩陣到第j個矩陣相乘的最少次數是dp[i][j]
int main()
{
    int n;//n個矩陣相乘
    cin>>n;
    for(int i=0;i<n;i++)//輸入矩陣的行數和列數
        cin>>p[i]>>p[i+1];
    memset(dp,0,sizeof(dp));
    for(int len=2;len<=n;len++)//區間長度
    {
        for(int i=1;i<=n;i++)//起始位置
        {
            int cnt=99999999;
            int j=i+len-1;//結束位置
            if(j>n)
                break;
            for(int k=i;k<j;k++)//分割點k
                cnt=min(cnt,dp[i][k]+dp[k+1][j]+p[i-1]*p[k]*p[j]);
            dp[i][j]=cnt;
        }
    }
    cout<<dp[1][n]<<endl;
    return 0;
}
相關文章
相關標籤/搜索