什么是在矩阵中找到M个相邻元素的最大总和的最快方法

时间:2015-12-05 16:15:43

标签: c++ algorithm matrix

假设我有一个尺寸为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;

}

2 个答案:

答案 0 :(得分:3)

此答案不包括代码(稍后),稍后将使用所述算法的实现进行扩展

主要的困难是某些&#34;形状&#34;经过多次处理。考虑一个填充矩形的选择。它可以从任何单元格开始并以多种不同的方式遍历(&#34;递归路径&#34;)以达到相同的选择(显然是相同的计算)。这个问题需要解决。

为此,您需要预先计算可以为给定的 M 选择的各种形状,然后迭代矩阵和每个单元格(作为顶部 - 形状的左侧)计算并比较所有形状选择的总和。

预计算是通过使用递归函数完成的,就像在#34; paint&#34; a (2M-1) 2 矩阵,路径中的单元格从中间开始。在最终条件(选择的M个单元格)中,将生成的形状与累积的形状列表&#34;中的现有形状进行比较,并且仅在它尚未存在时才添加。 需要解决&#34; +&#34;形状场景

应在预计算阶段使用优化以避免&#34;转印&#34;例如,从非常大的 M 的计算到预计算阶段的问题,限制遍历,使得超出起始行是非法的(因此,形状矩阵只需要是 M(2M-1)大)。

答案 1 :(得分:1)

这是Python中的基本深度优先搜索,使用集合来散列形状(这是我的答案的修订版,Maximum sum of k connected elements of a matrix)。在我看来,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
"""