找到矩阵中M个相邻元素的最大和的最快方法是什么
Whats the fastest way to find biggest sum of M adjacent elements in a 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;
}
这个答案(还)不包括代码,稍后将通过所述算法的实现进行扩展
主要的困难是某些"形状"要经过多次处理。考虑一个填充矩形的选择。它可以从任何单元格开始,以多种不同的方式("递归路径")遍历,以达到相同的选择(显然也是相同的计算)。正是这个问题需要解决。
为此,您需要预先计算可以为给定M选择的各种形状,然后迭代矩阵,并为每个单元格(用作形状的左上角)计算和比较所有形状选择的总和。
预计算是通过使用递归函数来完成的,就像在"绘制"一个(2M-1)2矩阵的问题中一样,该矩阵包含路径中的单元格,从在中间开始。在结束条件下(选择M个单元格),生成的形状将与累积的"形状列表"中的现有形状进行比较,并且只有在不存在时才添加
需要解决"+"形状场景。
优化应在预计算阶段使用,以避免将问题从计算"转移"到非常大的Ms的预计算阶段,例如,限制遍历,使其超过起始行是非法的(因此,形状矩阵只需要M(2M-1)big)。
这是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
"""
相关文章:
- int数据类型的指针指向的是什么,如果是一个类的私有数据成员,我们创建了该类的两个对象?
- 组装指令中乘法的下部和上部是什么
- B不接受8作为输入的是什么?C++
- 结构块指的是什么?
- 使用此网格函数的立方体的正确顶点和索引是什么
- 梯度幅度的单位和极限是什么
- 模板化代码的语法和语义是什么C++
- Google协议重复值如何结构化?他们的局限性和优势是什么
- 在C++中使用异常的可能的错误处理策略是什么,它们的后果和影响是什么
- 封闭环变量的生存期和范围是什么
- 在此地图中,取消运算符的目的和功能是什么
- 以不同方式实现可变参数构造函数的模板类:每个版本的优点和缺点是什么
- C++中strstr()函数的时间复杂度、空间复杂度和算法是什么
- 在C++程序的主要函数中,“return 0”的作用和含义是什么
- c++中的apvector和apstring是什么?
- char和CString的区别和关系是什么?
- 着色器中的gl_NormalMatrix和gl_ModelViewMatrix是什么
- C# 中类型推断的优点和缺点是什么?
- 当我从赋值操作符返回值时,首先,调用复制构造函数的机制和基础是什么?
- 单例类的确切用法和实现是什么?