用于查找可放置在网格中的最大项目的算法

时间:2012-08-09 03:29:15

标签: algorithm

二维空间中有一个NXM点网格。可以将项目放置在点(x,y)处,使得在(x + 2,y-2)或(x-2,y-2)或(x-2,y + 2)处不能有另一个项目)或(x + 2,y + 2)。此外,网格中的几个点被卡住,即物品不能放置在这些点上。

那么如何找到可以放在网格中的最大项目数。

3 个答案:

答案 0 :(得分:0)

没有这些阻塞点的最佳包装将放在列

(a + 0), (a + 3), (a + 6), ..., (a + 3*n)

如果这些列之外存在块,则无法进行任何改进。如果列上存在块,则在(x,y)处,您可以将点放在(x + 2,y-2)和(x-2,y-2)上。因此,请查看所有列并尝试将它们置于最小化列上的块数。 (请注意,这表示之前最大化。我昨晚也睡了3小时。)

检查这个可以在n * m步骤中完成。

答案 1 :(得分:0)

我认为将网格视为圆环是一种说明,即两侧“环绕”(顶部 - >底部,左侧 - >右侧),以便您可以忽略边缘情况。当N和M很大时,无论如何这都是一个很好的近似值。

在环面上,每个点必然会阻挡现有的两个其他点,但您可以重叠排除,即一个点的(x+2, y-2)是另一个点(x+2, y-2)。因此,您可以达到的最大包装为1/2。这可以通过交替的柱条实现:2个完整列,2个空列,2个完整列等等。

我会离开角落的情况(M不是4的倍数)。

在一个不是圆环的网格上,你有两个考虑因素。首先,您可以直接将完整列启动到网格的边缘。你也可以完全填充底部的两行(“底部”是最小的y)。因此,您可以实现比1/2更好的打包,但是当尺寸接近无限时,您仍然会获得1/2。

答案 2 :(得分:0)

考虑更简单的1d问题:给定一个长度为n的数组,其中包含阻塞的单元格,有多少种方法可以填充它,如果x处有1,则没有1 x - 2x + 2

请注意,这是一个多余条件:如果我们在x处有一个1,那么1号就足够x - 2(如果x + 2处有1,那么将打破这种减少的条件)。

dp[i, j] = number of ways to populate 1 .. i with points such that the last element is j

我们有:

dp[i, 0] = dp[i - 1, 0] + dp[i - 1, 1] <- no 1 at i
dp[i, 1] = 2 * dp[i - 2, 0] <- we MUST have 0 at i - 2, but i - 1 can have whatever
=> if i is blocked dp[i, _] = dp[i - 1, _]

示例:

n = 3
brute force solutions:
000
010
100
001
110
011
=> 6
dp[0, 0] = 1 dp[0, 1] = 0
dp[1, 0] = 1 dp[1, 1] = 1
dp[2, 0] = 2 dp[2, 1] = 2
dp[3, 0] = 4 dp[3, 1] = 2
=> dp[3, 0] + dp[3, 1] = 6

同样可以用于您的问题。注意条件可以减少到“如果在(x - 2,y - 2)和(x + 2,y - 2)处没有点,则可以在(x,y)处有一个点” 即可。然后在O(lines*columns)中迭代并填写dp矩阵。