二维空间中有一个NXM点网格。可以将项目放置在点(x,y)处,使得在(x + 2,y-2)或(x-2,y-2)或(x-2,y + 2)处不能有另一个项目)或(x + 2,y + 2)。此外,网格中的几个点被卡住,即物品不能放置在这些点上。
那么如何找到可以放在网格中的最大项目数。
答案 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 - 2
和x + 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矩阵。