我需要一种算法来计算长度X的最大可能平方数,它可以在M x N矩形内拟合,并具有网格可用性的约束。
例如 当X = 2且M = N = 8(不能使用灰色网格)时
我们在这个矩形内部最多可以得到10个方格。 如下面的解决方案,可能有多个解决方案空间,以实现最大计数。
[注意:我认为贪婪不会在这里工作,如果我错了,请纠正我]
请描述您所知道的最佳方法。
答案 0 :(得分:2)
根据要求,对于 X = 2,您可以将DP与位掩码一起使用。您可以按列或行进行操作,因此通常会选择较小的列。我们假设最小数是列数。
您可以执行一个DP,其中状态是当前行,当前列和位掩码,告知当前行中哪些列被阻止。
让我用你的例子解释一下。
原始状态:row = 0, column = 0, bitmask = 00000000
。
检查您是否可以在当前位置放置一个正方形,在这种情况下,您可以。结果将是max(1 + placing the square, not placing the square)
。如果你不能,那么你只有一个选择:不放置它。
如果您没有放置方格,则下一个状态为row = 0, column = 1, bitmask = 00000000
。请注意,现在第一位是告诉下一行,而不是当前已经通过该列的当前行。
如果你放置正方形,你的下一个状态是row = 0, column = 2
(我们因为正方形而跳了两个)和bitmask = 11000000
。该位掩码告诉您第二行的前两个位置已被阻止。
现在让我们考虑一个不同的状态row = 2, column = 4, bitmask = 11110000
。当您处于第三行和第五列时,这与您的解决方案的情况相对应。位掩码告诉我们下一行的四个第一个单元格已被阻塞,当前行的四个下一个单元格是空闲的。
再次,你检查你是否可以放置方块。单元格没有被阻挡,但网格包含一个标记的单元格,所以你不能。接下来的状态是row = 2, column = 5, bitmask = 11110000
。在这个例子中,我希望你注意到位掩码并没有告诉你关于被原始网格阻挡的单元格的任何信息,而只是通过你之前的方块。
因此,每个状态都会在恒定时间内进行检查,因此算法的复杂性就是状态数,即O(NM * 2^(min(N, M)))
,抱歉,我在评论中忘记了一个额外的因素。