计算可能序列的数量

时间:2012-03-14 16:52:54

标签: algorithm permutation counting

我最近在接受采访时遇到了以下问题。

有一个序列{a1, a2, a3, a4, ..... aN}。 运行是序列的最大严格增加或严格减少的连续部分。 例如。如果我们有序列{1,2,3,4,7,6,5,2,3,4,1,2} 我们有5次可能的投放{1,2,3,4,7}{7,6,5,2}{2,3,4}{4,1}{1,2}

给出四个数字NMKL。计算完全N次运行的M个数字的可能序列数,序列中的每个数字小于或等于K,相邻数字之间的差值小于等于L

3 个答案:

答案 0 :(得分:1)

可能有一种分析方法可以分析并提出O(1)解决方案。然而,这将需要一个比我聪明的人来弄清楚:)这是一个动态编程解决方案。

我假设这个解决方案所有值必须是正数。此外,我假设序列中的所有值必须不等于先前值。在这个问题中,这两个条件似乎都暗示着,但从未明确说明。


首先,让我们稍微改变一下问题,这样除了NMKL之外,我们还会给出最后一个值。序列中的术语, n 。我们还要添加另一个变量I,它表示最后一个项是否是增加或减少序列的一部分。然后我们将定义一个函数F,以返回给定所有这些值的可能序列的数量。

N = number of values in sequence
M = number of "runs" in the sequence
K = max value allowed
L = max difference between adjacent sequence terms
I = whether the last term is increasing or decreasing
an = last term in the sequence
FK,L(N,M,I,an) = number of possible sequences, given all these values

现在,如果我们有办法计算F,我们可以将 n (从1到K)和{的所有可能值相加{1}}以获得问题的答案。


我们假设我=“增加”。我们想用“较小”值表示 F K,L (N,M,“增加”, n I,因此我们可以递归计算F的值以获得最终值。我们将通过将F的值与 a n-1 的所有可能值相加来实现此目的;也就是说,我们基本上说F等于长度为F的有效序列, > / strong>,然后我们想象为每个人添加 a n

因为我们知道 a n 是增加序列(I =“增加”)的一部分,我们知道 a n-1 &lt; a n (我们很快就会看到另一个案例)。我们还知道 a n-1 必须在 a n-1 N-1范围内;因此 max(1,a n -L)&lt; = a n-1 &lt;一个<子>名词

我们现在要考虑两个案例,具体取决于前一个术语 a n-1 是增加还是减少:

  1. n-1 增加。然后我们还在增加,所以我们感兴趣的L的价值是 的˚F<子> K,L (N-1,M, “提高”,一个<子> N-1 即可。
  2. n-1 正在减少 a n 现在正在增加,因此现在将再增加一次“运行”值。因此,我们感兴趣的F的值是
    ˚F<子> K,L (N-1,M-1, “降低”,一个<子> N-1 即可。
  3. 我们对 a n-1 的所有可能值汇总所有这些情况,以获得 F K,L 的值(N,M, “提高”,一个<子>名词即可。我们可以用类似的方式找到 F K,L (N,M,“递减”, n ,只有我们限制 a n-1 a n &lt; a n-1 &lt; = min(K,a n + L),我们从#{1}}中减去1,而不是#1}情况#2。


    最后,我们陈述基本案例。 F K,L (N,M,I,a n ):如果M <0,则为0。 1或M> N; 1如果N = 1

    然后,如上所述,只需将 F K中的F a n 的所有值相加,L < / sub>(N,M,I,a n 以获得原始问题的答案。运行时复杂性为M

答案 1 :(得分:0)

我会按如下方式解决问题。运行必须在增加和减少之间交替,因此重要数字是方向转向的位置。对于上面的示例,重要数字为1 - 7 - 2 - 4 - 2,如下所示:

(1,2,3,4,7,6,5,2,3,4,1,2)
 x       x     x   x x x

假设您已经给出了这些转折点的位置和值,例如:你有

(1,7,2,4,1,2)

然后我们想要计算在数字之间填充的方法的数量。这仅取决于NL,因为我们已经使用KM中的约束来制作该骨架。这里的规则是缺少的数字在给定数字之间是单调的,并且跳跃不超过L。这是一个容易计数的问题(后面会详细介绍)。

接下来计算骨架的数量,这仅取决于KM(根据NL填充它们的计数可能为0)。我们对这些了解多少?没有间隙,这必须是长度为M+1的交替序列(上下 - 上下),其值在1K之间。同样,这是well studied并且不难计算。

我对这种方法的唯一犹豫是没有一种简单的方法可以将这两种方法结合起来,所以它不会给出一个干净的公式。然而,它仍然比彻底枚举解决方案有了很大的改进,也许这个想法可以进一步改进,以提供一个封闭或干净的递归公式。

答案 2 :(得分:0)

以下是一些提示:

帖子标签似乎暗示这是一次电话采访,这意味着你应该知道欧拉数字。更具体地说,总共M次上升加下行的N的排列数由2 * A(N,M / 2-1)给出,也写为

2*  /     N   \
    \ M/2 - 1 /

可以递归求解为结果的2倍:

let x = M/2-1; then
A(n,x)=(n-x)*A(n-1,x-1)+(x+1)*A(n-1,x)

另外两个限制k和L用于控制置换周期的形式。例如,如果L = 3则不允许排列{9,1,3,6,2},因为在循环[1,2,9]中,9太大了。

您的简历可能会让您成为组合学专家,这只是意味着您需要查看学校笔记。无论如何,我希望这会让你走上正轨。