算法提高 矩阵乘法
算法提高 矩阵乘法
时间限制:3.0s 内存限制:256.0MB
问题描述
有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。
本来赋的INF是0x3f3f3f,一直有两组过不了!
两个相邻的数字之说明这是一个矩阵,计算次数为0,当两个数字中间相隔一个数字的时候,计算次数为三者相乘。
#include <iostream> #include <cstdio> #include <vector> #include <queue> #include <map> #include <stack> #include <cstring> #include <algorithm> #include <cstdlib> #define FOR(i,x,n) for(long i=x;i<n;i++) #define ll long long int #define INF 0x3f3f3f3f3f3f3f3f #define MOD 1000000007 #define MAX_N 50005 using namespace std; ll m[1005][1005]; ll a[1005]; int main() { //freopen("input1.txt", "r", stdin); //freopen("data.out", "w", stdout); int N; scanf("%d",&N); FOR(i,0,N+1){ scanf("%lld",&a[i]); } FOR(i,0,N+1){ FOR(jj,0,N+1-i){ int j=jj+i; if(i==0||i==1){ m[jj][j]=0; }else if(i==2){ m[jj][j]=a[jj]*a[jj+1]*a[j]; }else if(i>2){ ll minn=INF; FOR(k,jj+1,j){ if(k==jj+1){ ll t=m[k][j]+a[jj]*a[k]*a[j]; if(minn>t){ minn=t; } }else if(k==j-1){ ll t=m[jj][k]+a[jj]*a[k]*a[j]; if(minn>t){ minn=t; } }else{ ll t=m[jj][k]+m[k][j]+a[jj]*a[k]*a[j]; if(minn>t){ minn=t; } } } m[jj][j]=minn; } } } printf("%lld",m[0][N]); //fclose(stdin); //fclose(stdout); return 0; }