问题要求我们找出将R币放置在N * M网格上的方式的数量,使得每行和每列至少有一枚硬币。给出的约束是N,M <1。 200,R&lt; N * M个。我最初想的是回溯,但我意识到它永远不会及时完成。有人可以指导我另一种解决方案吗? (DP,封闭形式公式。)任何指针都会很好。感谢。
答案 0 :(得分:1)
根据OEIS sequence A055602,一个可能的解决方案是:
Let a(m, n, r) = Sum_{i=0..m} (-1)^i*binomial(m, i)*binomial((m-i)*n, r)
Answer = Sum_{i=0..N} (-1)^i*binomial(N, i)*a(M, N-i, R)
您需要为a。
评估N + 1个不同的值假设你有预先计算的二项式系数,a的每个评估都是O(M),所以总复杂度是O(NM)。
此公式可以使用inclusion-exclusion principle两次派生。
a(m,n,r)是将r币放在大小为m * n的网格上的方式的数量,使得m列中的每一列都被占用,但并非所有行都必须被占用。
包含 - 排除将此转换为正确答案。 (我们的想法是从(M,N,R)得到我们的第一个估计值。这高估了正确答案,因为并非所有行都被占用所以我们减去a(M,N-1,R)的情况我们只占用N -1行。然后低估了所以我们需要再次纠正...)
类似地,我们可以通过考虑b(m,n,r)来计算a(m,n,r),b(m,n,r)是将r硬币放在网格上的方式的数量,我们不关心被占用的行或列。这可以简单地从在网格大小m * n中选择r个位置的方式的数量导出,即二项式(m * n,r)。我们使用IE将其转换为函数a(m,n,r),我们知道所有列都被占用。
如果您想对每个方格上的硬币数量允许不同的条件,那么您只需将b(m,n,r)更改为适当的计数功能。
答案 1 :(得分:0)
这很难,但是如果你开始计算每行和每列至少有一枚硬币的数量(称之为储备硬币)。答案将是#1 (n! / r! (n - r)!) *
的产品,其中#2 n = N*M - NUMBER_OF_RESERVE_COINS
和#3 r = (R - NUMBER_OF_RESERVE_COINS)
为#4,每个排列在每行/每列上保留一个硬币。
abs(N-M)
告诉您单个行/列上将有多少预留硬币。我无法确定进入下一步的正确方法,主要是由于时间不够(虽然我可以在周末回到这里),但我希望我已经为您提供了有用的信息,如果我是已经说过你能够完成这个过程是正确的。