蓝桥杯 矩阵乘法(区间DP)
问题描述
有n个矩阵,大小分别为a0*a1, a1*a2, a2*a3, ..., a[n-1]*a[n],现要将它们依次相乘,只能使用结合率,求最少需要多少次运算。
两个大小分别为p*q和q*r的矩阵相乘时的运算次数计为p*q*r。
两个大小分别为p*q和q*r的矩阵相乘时的运算次数计为p*q*r。
输入格式
输入的第一行包含一个整数n,表示矩阵的个数。
第二行包含n+1个数,表示给定的矩阵。
第二行包含n+1个数,表示给定的矩阵。
输出格式
输出一个整数,表示最少的运算次数。
样例输入
3
1 10 5 20
1 10 5 20
样例输出
150
数据规模和约定
1<=n<=1000, 1<=ai<=10000。
分析:要让1由到n的矩阵相乘计算次数最小
可以把[1,n]分成一个个小区间
让每个小区间的计算次数最小
于是可以用区间DP
状态转移方程为 dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+a[i]*a[k]*a[j]);
由于题目中的数据相乘很大 故用long long的定义方式
代码如下:
#include <cstdio> #include <iostream> #include <algorithm> using namespace std; long long a[1100]; long long dp[1100][1100]; int main() { int n,j; scanf("%d",&n); n=n+1; for(int i=1;i<=n;i++) scanf("%lld",&a[i]); for(int L=1;L<=n-1;L++) { for(int i=1;i<=n-L;i++) { j=i+L+1; dp[i][j]=-1; for(int k=i+1;k<j;k++) { if(dp[i][j]<0)dp[i][j]=dp[i][k]+dp[k][j]+a[i]*a[k]*a[j]; else dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+a[i]*a[k]*a[j]); } } } cout<<dp[1][n]<<endl; return 0; }