有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
答案 0 :(得分:0)
查看此递归函数。它为给定的n, k
和last
标志计算变体的数量(它显示我们是否在最后一栏中标记了单元格)。
如果我们不在当前列中标记单元格,那么下一个变量将具有三个变体:不要再次标记,顶部标记,底部标记。
如果我们在当前列中标记单元格,那么下一个变量只有两个变体:不要再次标记或在相对行中标记单元格。
请注意,对于第二个示例,代码返回正确的结果 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