Самый быстрый способ найти большую сумму M смежных элементов в матрице
Предположим, что у меня есть квадратная матрица размерности N (N <= 50), а смежные элементы не включают диагонали.
Как найти самую большую сумму между M смежными элементами, учитывая M?
Например, возьмите эту матрицу 4x4:
Matrix: For M = 3 For M = 4
3 1 5 2 3 1 5 2 3 1 5 2
2 6 1 3 2 [6] 1 3 2 [6] 1 3
1 4 4 2 1 [4][4] 2 1 [4] 4 2
5 3 2 7 5 3 2 7 [5][3] 2 7
Biggest = 14 Biggest = 18
Я попытался сделать этот путь, но после определенного измерения он очень медленный.
#include <bits/stdc++.h>
using namespace std;
int mat[51][51];
int mark[51][51];
int m, n;
int biggest;
void search(int row, int column, int sum, int steps){
if(row < 0 || row >= n || column < 0 || column >= n || mark[row][column]) {
return;
}
sum += mat[row][column];
mark[row][column] = 1;
if(steps == m){
if(biggest < sum) biggest = sum;
}
else{
search(row - 1, column, sum, steps+1);
search(row + 1, column, sum, steps+1);
search(row, column + 1, sum, steps+1);
search(row, column - 1, sum, steps+1);
}
mark[row][column] = 0;
}
int main(){
memset(mat, 0, sizeof(mat));
memset(mark, 0, sizeof(mark));
biggest = 0;
scanf("%d", &n);
scanf("%d", &m);
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
scanf("%d", &mat[i][j]);
}
}
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
search(i, j, 0, 1);
}
}
printf("%d", biggest);
return 0;
}
Ответы
Ответ 1
Этот ответ не включает код (пока) и позже будет расширен с помощью реализации описанного алгоритма
Основная трудность заключается в том, что определенные "фигуры" обрабатываются много раз. Рассмотрим выбор, который является заполненным прямоугольником. Он может начинаться с любой ячейки и проходить несколькими способами ( "рекурсивными путями" ) для достижения одного и того же выбора (и, очевидно, того же вычисления). Именно эту проблему нужно решать.
Для этого вам необходимо предварительно обдумать различные формы, которые могут быть выбраны для данного M, затем перебрать матрицу и для каждой ячейки (выступающей в левом верхнем углу формы) вычислить и сравните сумму для всех вариантов формы.
Предвычисление выполняется с использованием рекурсивной функции, как в вопросе о том, что "рисует" матрицу (2M-1) 2 с ячейками на пути, начиная с середины, В конечном состоянии (выбранные М-ячейки) сгенерированная форма сравнивается с существующими фигурами в накопительном "списке форм" и добавляется только в том случае, если она еще не существует. необходимо решить для формы "+" сценарий.
Оптимизация должна использоваться на этапе прекомпуты, чтобы избежать "переноса" проблемы с вычисления на этап предварительной вычисления для очень больших Ms, например, для обхода границ, так что незаконно идти выше стартовой строки (и как результат, матрица формы должна быть только M (2M-1) большой).
Ответ 2
Здесь элементарный поиск по глубине в Python с использованием наборов для хэш-фигур (это ревизия моего ответа здесь Максимальная сумма k связанных элементов матрицы). Мне кажется, что DFS должен хранить размер стека порядка O(m)
(хотя пространство поиска по-прежнему огромно).
from sets import Set
def f(a,m):
stack = []
hash = Set([])
best = (0,[]) # sum, shape
n = len(a)
for y in range(n):
for x in range(n):
stack.append((a[y][x],Set([(y,x)]),1))
while len(stack) > 0:
s,shape,l = stack.pop()
key = str(sorted(list(shape)))
if l == m and key not in hash:
hash.add(key)
if s > best[0]:
best = (s,shape)
elif key not in hash:
hash.add(key)
for (y,x) in shape:
if y < n - 1 and (y + 1,x) not in shape:
copy = Set(shape)
copy.add((y + 1,x))
stack.append((s + a[y + 1][x],copy,l + 1))
if y > 0 and (y - 1,x) not in shape:
copy = Set(shape)
copy.add((y - 1,x))
stack.append((s + a[y - 1][x],copy,l + 1))
if x < n - 1 and (y,x + 1) not in shape:
copy = Set(shape)
copy.add((y,x + 1))
stack.append((s + a[y][x + 1],copy,l + 1))
if x > 0 and (y,x - 1) not in shape:
copy = Set(shape)
copy.add((y,x - 1))
stack.append((s + a[y][x - 1],copy,l + 1))
print best
print len(hash)
Вывод:
matrix = [[3, 1, 5, 2,]
,[2, 6, 1, 3,]
,[1, 4, 4, 2]
,[5, 3, 2, 7]]
f(matrix,4)
"""
(18, Set([(3, 1), (3, 0), (2, 1), (1, 1)]))
205 hash length
"""