N个不同半径的圆可以排成一行的方式

时间:2017-01-15 13:09:37

标签: algorithm combinatorics

问题:给出一个由11个单位分隔的线上的M个点。找出可以绘制不同半径的N个圆圈的方式,以便它们不相交或重叠,或者一个在另一个内部?假设圆心应该是那些MM点。

示例1:N = 3,M = 6,r1 = 1,r2 = 1,r3 = 1答案:24路。

示例2:N = 2,M = 5,r1 = 1,r2 = 2答案:6种方式。

实施例3:N = 1,M = 10,r = 50。答案= 10种方式。

我在网上发现了这个问题,直到现在还没有解决。到目前为止,我已经能够解决这个问题了,任何一个圆圈都可以从n-rn-r到n-2rn-2r。但在其他问题中,我如何调整半径为33的圆占n-4n-4th点的边缘情况,现在最后一个点将保持不变,但我不能放置任何半径大于1的圆。我不是能够看到任何广义的数学解决方案。

1 个答案:

答案 0 :(得分:0)

如果圆的中心可以放在非整数x和y坐标上,那么由于长度太短,要么是不可能的,要么由于有足够的长度而无限多,并且有无限多的翻译。 / p>

所以,既然你必须计算结果,我会假设(M,M)的坐标是整数。

如果只有一个圆圈,则解决方案是合法放置圆圈的点数。

如果至少有两个圆圈,那么你需要计算直径的总和,如果这恰好大于我们所说的线的总长度,那么你没有解决方案。如果不是这种情况,则需要从总长度中减去直径总和,得到补体。你也有N!用于计算圆的顺序的排列。您将拥有Complementer - 1个可能的位置,您可以在这些位置分配圆圈之间的间隙。间隙的长度为G1,...,Gn-1

我们知道G1 + ... + Gn-1 =补充者

G1,...,Gn-1的可能分布数是D.因此公式为b

N! * D

剩下的问题是:我们如何计算D?

解决方案:

function distr(depth, maxDepth, amount)
    if (depth = maxDepth) then
        return 1 //we need to put the remaining elements on the last slot
    end if
    sum = 1 //if we put amount here, that is a trivial case
    for i = amount - 1 to 0 do
        sum = distr(depth + 1, maxDepth, amount - i)
    end for
    return sum
end distr

你需要调用distr,深度= 1,maxDepth = N-1,amout = Complementer