读题过后,可以提取出来目的是做一系列矩阵乘法,只要涉及到矩阵乘法就要考虑维度的问题,本题中n≤10000,d≤20,如果按顺序直接计算,会有一次运算达到n × n × d的次数,所以根据矩阵运算的结合律可以让K的转置和V先进行乘法,可以大量减少运算次数以得到更短的运行时间。
#include<iostream>
using namespace std;
const int N = 10001;
const int D = 21;
int Q[N][D];
int K_T[D][N];
int V[N][D];
int W[N];
long long tem1[D][D];
long long tem2[N][D];
int main(){
int n,d;
cin >> n >> d;
//input Q
for(int i = 0; i < n;i++){
for(int j = 0; j < d; j++){
cin >> Q[i][j];
}
}
//input K_T
for(int i = 0; i < n; i++){
for(int j = 0; j < d;j++){
cin >> K_T[j][i];
}
}
//input V
for(int i = 0; i < n;i++){
for(int j = 0; j < d; j++){
cin >> V[i][j];
}
}
//input W
for(int i = 0; i < n;i++){
cin >> W[i];
}
//compute Kt*V load in tem1
for(int i = 0; i < d; i++){
for(int j = 0;j < d;j++){
tem1[i][j] = 0;
for(int k = 0; k < n;k++){
tem1[i][j] += K_T[i][k] * V[k][j];
}
}
}
//compute W dot (Q*tem1) load in tem2
for(int i = 0; i < n; i++){
for(int j = 0;j < d;j++){
tem2[i][j] = 0;
for(int k = 0; k < d;k++){
tem2[i][j] += Q[i][k] * tem1[k][j];
}
tem2[i][j] *= W[i];
}
}
for(int i = 0; i < n; i++){
for(int j = 0;j < d;j++){
cout << tem2[i][j] << " ";
}
cout << endl;
}
return 0;
}