如何从起点找到2d数组中相邻元素的最大和

时间:2017-03-23 12:11:54

标签: algorithm dynamic-programming graph-algorithm path-finding greedy

有4x4 2d数组,例如,(每个元素的范围在0到9之间)

4512
3712
1345
3312

我试图从一个点找到最多4个相邻元素。 (不包括对角线)

例如,如果选择一个点(1,2)开始, 可以从(1,2)移动(1,1)或(2,2)或(1,3)相邻元素。 如果你选择(2,2)下一个,你可以移动(2,1)或(3,2)或(2,3)。 等等,直到挑选4个元素。

如果选择4个元素, (1,2) - >(2,2) - >(2,1) - >(1,1) 总和是3 + 7 + 5 + 4 = 19

我正在尝试使用dfs或bfs制作候选人。

但是,它不能为候选人制作上述内容,(1,1) - > (1,2) - > (2,1) - > (2,2)

这个问题有什么解决方案吗?

3 个答案:

答案 0 :(得分:1)

一种可能的方法是创建5 tetrominoes的预定义常量(抱歉,不能发布图像),所有旋转和反射(当然,您不需要旋转' square =或反映对称的)。然后,您可以采用这些常量中的每一个,并将起点映射到所选常量的每个点。

另一种方法是在算法上枚举四联骨牌。 wikipedia中描述了一些算法。

答案 1 :(得分:0)

尚未完整答案

使用动态编程。

在sum数组中,位置(i,j)的值包含使用(i,j)元素和元素向右或向下的最大总和。

缺少链:不会考虑像(0,0),(0,1),(1,1)和(1,0)这样的元素链



var array = [
  [4, 5, 1, 2],
  [3, 7, 1, 2],
  [1, 3, 4, 5],
  [3, 3, 1, 2],
]

var sum1 = array;

var sum2 = getNextOrderSum(sum1, array);
var sum3 = getNextOrderSum(sum2, array);
var sum4 = getNextOrderSum(sum3, array);

print(sum4);

// Given max sum array of n adjacent elements and original array
// Return max sum array of n+1 adjacent elements
function getNextOrderSum(input, array) {
  var sum = [];
  for (var i = 0; i < input.length; i++) {
    sum[i] = [];
    for (var j = 0; j < input[0].length; j++) {
      sum[i][j] = array[i][j] + Math.max(get(input, i, j + 1), get(input, i + 1, j));
    }
  }

  return sum;
}

// Utility method to get i,j element of array with boundary checks
function get(array, i, j) {
  if (i < 0 || j < 0)
    return 0;
  if (i >= array.length)
    return 0;
  if (j >= array[0].length)
    return 0;

  return array[i][j];
}

// Utility method for printing
function print(array) {
  var s = "";
  for (var i = 0; i < array.length; i++) {
    s += array[i].toString() + "\n"
  }
  console.log(s);
}
&#13;
&#13;
&#13;

答案 2 :(得分:0)

使用3D阵列dp[n][m][4]

其中nm是数组的维度

并且4用于表示链中元素的位置。

基本情况 - 如果(i,j)或当元素是链中的最后一个或,如果dp[i][j][k]k=3,我们会在i中存储elment j的值是超出范围的数组(普通案例)。

DP公式 - 让用于执行任务的函数为dpFUNCTION()

dp[i][j][k]=array[i][j] + mAX( dpFUNCTION(i+1,j,k+1), dpFUNCTION(i,j+1,k+1), dpFUNCTION(i-1,j,k+1), dpFUNCTION(i,j-1,k+1));

修改 - 让我们从简单的案例开始,并将其扩展到您的问题。实际上你可以通过这种方式完成大多数DP问题,即通过简单的形式扩展它。

1)现在,如果我们只需要找到数组中相邻数字的最大数量,我们只需填充dp1[i][j] -

dp1[i][j]=max(array[i-1][j], array[i+1][j], array[i][j+1], array[i][j-1]);
//max of adjacent numbers

2)现在,如果我们必须找到最多2个相邻数字,我们可以使用我们的dp1[][]数组,如下所示 -

dp2[i][j]= max(array[i-1][j]+dp1[i-1][j], array[i-1][j]+dp1[i-1][j], array[i-1][j]+dp1[i-1][j], array[i-1][j]+dp1[i-1][j]);

对于长度为2的链,我们需要得到它的相邻数字(比如说array[i-1][j])和它的相邻数字的最大值(它被计算存储在dp [i-1] [j]中)的总和。然后我们将所有相邻数字的最大值存储在dp2中。

3)同样,如果链的长度为3,我们使用dp2[][]如下 -

dp3[i][j]= max(array[i-1][j]+dp2[i-1][j], array[i-1][j]+dp2[i-1][j], array[i-1][j]+dp2[i-1][j], array[i-1][j]+dp2[i-1][j]);

4)最后,对于长度为4的链,我们得到 -

dp4[i][j]= max(array[i-1][j]+dp3[i-1][j], array[i-1][j]+dp3[i-1][j], array[i-1][j]+dp3[i-1][j], array[i-1][j]+dp3[i-1][j]);

哪个是必需的解决方案,我所做的是将所有这4个阵列归入dp[n][m][4]并填充一点混乱的方式而不是按照解释的步骤进行。即使包含对角线,您也可以使用相同的方法。