思路:
- 通过改变矩阵乘法顺序优化计算
- 合理评估数组大小与数据范围
代码:
#include<iostream>
using namespace std;
const int N=1e4+3;
const int D=25;
typedef long long ll;
int q[N][D],k[N][D],v[N][D];
ll ans[N][D],t[N][D]; //两步中间结果可能会超出INT范围
int w[N];
int main()
{
int n,d;
scanf("%d%d",&n,&d);
for(int i=0;i<n;i++)
for(int j=0;j<d;j++)
{
scanf("%d",&q[i][j]);
}
for(int i=0;i<n;i++)
for(int j=0;j<d;j++)
{
scanf("%d",&k[i][j]);
}
for(int i=0;i<n;i++)
for(int j=0;j<d;j++)
{
scanf("%d",&v[i][j]);
}
for(int i=0;i<n;i++)
{
scanf("%d",&w[i]);
}
//先计算矩阵K的转置与矩阵V的乘法
for(int c=0;c<d;c++)
for(int i=0;i<d;i++)
{
ll mid = 0;
for(int j=0;j<n;j++)
{
mid += k[j][c] * v[j][i];
}
t[c][i]=mid;
}
//计算Q与上一个计算所得矩阵的乘积,同时乘以W相量
for(int c=0;c<n;c++)
for(int i=0;i<d;i++)
{
ll mid = 0;
for(int j=0;j<d;j++)
{
mid += q[c][j] * t[j][i];
}
ans[c][i]=mid;
ans[c][i]*=w[c];
}
for(int i=0;i<n;i++)
{
for(int j=0;j<d;j++)
{
cout<<ans[i][j]<<" ";
}
puts("");
}
}