问题描述
有n个矩阵,大小分别为a0a1, a1a2, a2a3, …, a[n-1]a[n],现要将它们依次相乘,只能使用结合率,求最少需要多少次运算。
两个大小分别为pq和qr的矩阵相乘时的运算次数计为pqr。
输入格式
输入的第一行包含一个整数n,表示矩阵的个数。
第二行包含n+1个数,表示给定的矩阵。
输出格式
输出一个整数,表示最少的运算次数。
样例输入
3
1 10 5 20
样例输出
150
数据规模和约定
1<=n<=1000, 1<=ai<=10000。
类似于合并石子问题
子问题:矩阵i到j合并最小花费
确实是一个区间dp,但是我当时写的时候也有点乱,n个矩阵给你n+1个数,那么dp[1][n]就表示从第1个矩阵合并到第n个矩阵的最小花费。我们首先观察给你n+1个数,a[i]为其行数,a[i+1]为其列数,并且对于两个矩阵 p q q r 合并 则合并完后为p r. 花费为pqr; 也就是说对于(i,j)找到一个中间态的矩阵k,合并之后的花费为 a[i]a[k+1]a[j+1];(这是因为如果将i k两个矩阵合并后的话变为 a[i]a[k+1]的矩阵了 (第k个矩阵的列为a[k+1]))
1 | #include<iostream> |
错误代码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32#include<iostream>
using namespace std;
#define MAX 105
int n;
int mod=1000000007;
long long dp[MAX][MAX];
int num[MAX];
int main(){
fill(dp[0],dp[0]+MAX*MAX,0x3f3f3f);
cin>>n;
for(int i=0;i<n+1;i++)
cin>>num[i];
for(int i=0;i<n;i++){
dp[i][i+1]=num[i]*num[i+1];
if(i!=n-1)dp[i][i+2]=num[i]*num[i+1]*num[i+2];
}
for(int i=0;i<n+1;i++){
for(int j=i+1;j<n+1;j++){
for(int k=i+1;k<j;k++)
{
if(dp[i][j]>dp[i][k]+dp[k][j])
dp[i][j]=dp[i][k]+dp[k][j];
}
}
}
cout<<dp[0][n];
}
参考链接
https://blog.csdn.net/sinat_35637319/article/details/55253915