移除K个对象,使得没有两个相邻的对象

时间:2018-10-17 13:56:37

标签: combinatorics

有2行并排连接,每行n个对象。准确地删除k个对象,以使删除后没有两个空位彼此相邻的方式有多少种。

例如。 当n = 4时,k = 2的答案是18 当n = 5时,k = 3的答案是50。

对于任何n,k(k <= 2 * n)的值,我都无法求解该公式。image of how the two rows are joined

1 个答案:

答案 0 :(得分:0)

查看此递归函数。它为给定的n, klast标志计算变体的数量(它显示我们是否在最后一栏中标记了单元格)。

如果我们不在当前列中标记单元格,那么下一个变量将具有三个变体:不要再次标记,顶部标记,底部标记。

如果我们在当前列中标记单元格,那么下一个变量只有两个变体:不要再次标记或在相对行中标记单元格。

请注意,对于第二个示例,代码返回正确的结果 38 -存在C(5,3)=10组合,用于按列分配对象。带有不连贯的列10101的单个组合给出8个变体,带有01110的连成一体的列的三个组合给出3 * 2 = 6变体,而01011的六个组合给出6 * 4 = 24变体。

提供的代码无效(它具有指数复杂性),因此出于实际目的,应使用动态编程或记忆来重写(使用n / k / l键将调用结果保存在map中,并在需要时重新使用)或使用表格方法(逐个单元填充n / k / l个表格)。

对于作者来说,我认为这种转换比较容易(因为作者没有显示任何自己的代码)

def F(n, k, last):
    if k > n:
        return 0
    if k == 0:
        return 1
    if k == n:
        return 2 - last         # 2 if last==0 else 1

    return F(n - 1, k, 0) + (2 - last) * F(n - 1, k - 1, 1)

print(F(4,2,0))
print(F(5,3,0))

>>18
>>38