80.
This commit is contained in:
114
2023210/main.cpp
114
2023210/main.cpp
@@ -1,7 +1,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
struct CalcResult {
|
struct CalcResult {
|
||||||
int dim_sizes[32];
|
int dim_status;
|
||||||
int min_multiply_times;
|
int min_multiply_times;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -10,84 +10,134 @@ unsigned short *tensors;
|
|||||||
int n = 0, k = 0;
|
int n = 0, k = 0;
|
||||||
CalcResult *m;
|
CalcResult *m;
|
||||||
// CalcResult m[10000];
|
// CalcResult m[10000];
|
||||||
// int * m;
|
// int* m;
|
||||||
|
int dim_sizes[32] = {0};
|
||||||
|
|
||||||
|
int precalc[2][1048576] = {0};
|
||||||
|
|
||||||
int tensor_pos(int num, int dim) {
|
int tensor_pos(int num, int dim) {
|
||||||
return k * num + dim;
|
return k * num + dim;
|
||||||
}
|
}
|
||||||
|
|
||||||
int setm(int i, int j, int num, int *dims) {
|
int setm(int i, int j, int num) {
|
||||||
if (j < i) {
|
if (j <= i) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
m[(2 * n - i + 1) * i / 2 + j - i].min_multiply_times = num;
|
return m[(2 * n - i + 1) * i / 2 + j - i].min_multiply_times = num;
|
||||||
for (int i = 0; i < k - 2; i++) {
|
}
|
||||||
m[(2 * n - i + 1) * i / 2 + j - i].dim_sizes[i] = dims[i];
|
|
||||||
|
int getm(int i, int j) {
|
||||||
|
if (j <= i) {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return m[(2 * n - i + 1) * i / 2 + j - i].min_multiply_times;
|
return m[(2 * n - i + 1) * i / 2 + j - i].min_multiply_times;
|
||||||
}
|
}
|
||||||
|
|
||||||
CalcResult getm(int i, int j) {
|
int setmdim(int i, int j, int d) {
|
||||||
if (j <= i) {
|
if (j < i) {
|
||||||
return CalcResult{{0}, 0};
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return m[(2 * n - i + 1) * i / 2 + j - i];
|
return m[(2 * n - i + 1) * i / 2 + j - i].dim_status = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
CalcResult find_min(int start, int end) {
|
int getmdim(int i, int j) {
|
||||||
if (start == end || getm(start, end).min_multiply_times != 0) {
|
if (j < i) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m[(2 * n - i + 1) * i / 2 + j - i].dim_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int find_min(int start, int end) {
|
||||||
|
if (start == end || getm(start, end) != 0) {
|
||||||
return getm(start, end);
|
return getm(start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
int min = 2147483647;
|
int min = 2147483647;
|
||||||
int needed_multiply_by_d = 1;
|
int needed_multiply_by_d = 1;
|
||||||
|
int dim_status = getmdim(start, end);
|
||||||
|
|
||||||
// prepare the dims
|
// prepare the dims
|
||||||
int segment_dim_size[32] = {0};
|
// for (int i = 0; i < k - 2; i++) {
|
||||||
for (int dim = 0; dim < k - 2; dim++) {
|
// if ((dim_status >> i) & 1) {
|
||||||
for (int tens = start; tens <= end; tens++) {
|
// needed_multiply_by_d *= dim_sizes[i];
|
||||||
int d_k = tensors[tensor_pos(tens, dim)];
|
// }
|
||||||
if (d_k != 1) {
|
// }
|
||||||
needed_multiply_by_d *= d_k;
|
for (int i = 0; i <= (k - 2) / 16; i++) {
|
||||||
segment_dim_size[dim] = d_k;
|
needed_multiply_by_d *= precalc[i][(dim_status >> (16 * i)) & 0xffff];
|
||||||
break;
|
|
||||||
}
|
|
||||||
segment_dim_size[dim] = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int split_pos = start; split_pos < end; split_pos++) {
|
for (int split_pos = start; split_pos < end; split_pos++) {
|
||||||
// int a = tensors[tensor_pos(start, k - 2)];
|
|
||||||
// a = tensors[tensor_pos(split_pos, k - 1)];
|
|
||||||
// a = tensor_pos(end, k - 1);
|
|
||||||
int total_needed = tensors[tensor_pos(start, k - 2)] *
|
int total_needed = tensors[tensor_pos(start, k - 2)] *
|
||||||
tensors[tensor_pos(split_pos, k - 1)] * tensors[tensor_pos(end, k - 1)] *
|
tensors[tensor_pos(split_pos, k - 1)] * tensors[tensor_pos(end, k - 1)] *
|
||||||
needed_multiply_by_d;
|
needed_multiply_by_d;
|
||||||
CalcResult left = find_min(start, split_pos), right = find_min(split_pos + 1, end);
|
int left = find_min(start, split_pos), right = find_min(split_pos + 1, end);
|
||||||
total_needed += left.min_multiply_times + right.min_multiply_times;
|
total_needed += left + right;
|
||||||
if (total_needed < min) {
|
if (total_needed < min) {
|
||||||
min = total_needed;
|
min = total_needed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setm(start, end, min, segment_dim_size);
|
setm(start, end, min);
|
||||||
return getm(start, end);
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
void preparedim(int length) {
|
||||||
|
if (length == 1) {
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
int cur_stat = 0;
|
||||||
|
for (int j = 0; j < k - 2; j++) {
|
||||||
|
if (tensors[tensor_pos(i, j)] != 1) {
|
||||||
|
cur_stat |= 1 << j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setmdim(i, i, cur_stat);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
preparedim(length - 1);
|
||||||
|
for (int i = length - 1; i < n; i++) {
|
||||||
|
setmdim(i - length + 1, i, getmdim(i - length + 1, i - 1) | getmdim(i, i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
scanf("%d %d", &n, &k);
|
scanf("%d %d", &n, &k);
|
||||||
tensors = new unsigned short[n * k];
|
tensors = new unsigned short[n * k];
|
||||||
m = new CalcResult[(n + 1) * n / 2];
|
m = new CalcResult[(n + 1) * n / 2];
|
||||||
|
|
||||||
|
for (int i = 0; i < 32; i++) {
|
||||||
|
dim_sizes[i] = 1;
|
||||||
|
}
|
||||||
|
// m = new int[(n + 1) * n / 2];
|
||||||
for (int tensor_count = 0; tensor_count < n; tensor_count++) {
|
for (int tensor_count = 0; tensor_count < n; tensor_count++) {
|
||||||
for (int dim = 0; dim < k; dim++) {
|
for (int dim = 0; dim < k; dim++) {
|
||||||
scanf("%hu", &tensors[tensor_pos(tensor_count, dim)]);
|
scanf("%hu", &tensors[tensor_pos(tensor_count, dim)]);
|
||||||
|
if (tensors[tensor_pos(tensor_count, dim)] != 1) {
|
||||||
|
dim_sizes[dim] = tensors[tensor_pos(tensor_count, dim)];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%d\n", find_min(0, n - 1).min_multiply_times);
|
for (int i = 0; i < 2; i++) {
|
||||||
|
for (int j = 0; j < 0xffff; j++) {
|
||||||
|
int prod = 1;
|
||||||
|
for (int r = 0; r < 16; r++) {
|
||||||
|
if ((j >> r) & 1) {
|
||||||
|
prod *= dim_sizes[i * 16 + r];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
precalc[i][j] = prod;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
preparedim(n);
|
||||||
|
|
||||||
|
printf("%d\n", find_min(0, n - 1));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user