我正在寻找一种F(n ^ 3)技术,以查找使用以下规则填充n x n矩阵的所有可能方法:每行和每列只能有一个-1和一个1。每行和每一列的总和必须为0。N <=500。输入中可能已经放置了1和-1。矩阵的所有其他条目均为0。
我已经尝试过回溯,但是由于输入的大小可能太慢。 解决方案应显示为mod 10 ^ 9-7
答案 0 :(得分:0)
在键入此答案时,我忘记了“ F(n ^ 3)”部分。也许从输入中提取“数字”(见下文)需要n ^ 3算法。
这里要注意的主要事情是,您不应该生成所有可能的填充矩阵。输出只是一个数字。因此,如果您可以找到一个合适的方程式,那将是您的“算法”。
要注意的另一件事是,您输入的内容与这些非空单元格的所有位置都不相关。重要的是这九个数字:
以下是概念矩阵形式的这七个案例,如果您不以书面形式理解它们,这将是没有意义的:
1 0 | -1 0 | 1 -1 | 1 0 | 0 0 | 0 | 1 -1 | -1 1 | 1 -1
0 | 0 | 0 0 | -1 0 | | 0 | -1 0 | 1 0 | -1 1
您必须从输入中提取前9个数字中的前8个数字,这已经是一件不错的工作了。最后一个不是那么重要,因为该四联体已经填充并且“不可合并”。
您还必须弄清楚如何使用这八个数字。您基本上必须弄清楚哪些概念性矩阵片段可以“合并”在一起以形成完整的矩阵片段(不带空格),然后找到用剩余的1和-1填充这些片段的方式数量这些数字。
最后一部分是模运算,但是那部分很容易。确保前面只有乘法,并且在每次乘法之后都要进行模运算。最大乘积可以是99999993 * 500 = 49999996500,该值大于最大32位整数,但不大于最大64位整数。因此,最简单的方法是使用64位算术进行所有运算。
编辑:我只是意识到这个答案并不完全完整甚至正确。我认为矩阵片段可以以简单明了的方式进行合并,只能成对合并,但是合并的长条可能会无休止地组合在一起。 (许多个1可以合并在一起,而不仅仅是两个)。因此,最后没有一个简单的方程式。也许您仍然可以使用答案的概念,但是只需更多的编码即可。
答案 1 :(得分:0)
请注意,如果我们在每一列和每一行上都有-1和1,并且其中有2n,则我们满足所有条件。
要对此进行计数,我们可以执行以下操作(需要添加备注):
func count (idx, x, bool alreadyPlaced):
if idx == last:
return alreadyPlaced
if alreadyPlaced:
return (n - x - f(idx)) * count(idx + 1, x + 1, alreadyPlaced)
else:
return (n - x - f(idx) - 1) * count(idx + 1, x + 1, false) + count(idx + 1, x + 1, true)
有了这个,我们知道在网格上放置1的方式的数量。现在剩下的就是计算放置-1的方法的数量并将其乘以2。
将其余的作为练习,但如果您无法解决,请告诉我。