给定n和k,k <= n。
在多少种方式中,我们可以从集{1,2,...,n}中精确选择'k'个不同的数字,这样每个选中的数字'a'中至少有一个'a-1','a + 1'也被选中了?
时间复杂度 O(n * k)的动态编程解决方案是众所周知的。我们能做得更好吗?
答案 0 :(得分:3)
是的,我们只需要做一些组合学。
将运行定义为连续整数的最大子集。我们让r的范围从1到floor(k / 2),并用r运行求和子集的数量。
为了计算具有给定运行次数r的子集的数量,我们采用(a)分区运行长度的方式的次数(b)在运行之间划分间隙的方式的数量。
对于(a),将整数k划分为大于或等于2的r个整数之和的方法的数量是((k-2r +(r-1))select(r-1))by标准技术。
对于(b),将整数n - k划分为r + 1个整数的方法的数量,其中所有都是非负的,除了第一个和最后一个都是正的是((n - k - (r - 1)+ r)选择r)。
天真地,这个公式需要O(k ^ 2)算术运算,但如果我们使用r - 1的二项式系数计算r的那些,那么运行时间就变成O(k)算术运算。