计算严格增加的序列

时间:2014-11-05 19:28:06

标签: algorithm

我从左到右对齐了N个蜡烛。左边的第i个蜡烛具有高度Hi和颜色Ci,整数范围从1到给定的K,即颜色的数量。

问题:有多少严格增加(高度)的彩色子序列?如果每个K颜色在子序列中出现至少一次,则子序列被认为是彩色的。

For Ex: N=4 k= 3
      H   C
      1    1
      3    2  
      2    2
      4    3 

只有两个有效的子序列是(1,2,4)和(1,3,4)

我认为这是Fenwick Tree的一个问题,请为我提供一个如何处理此类问题的方法

1 个答案:

答案 0 :(得分:1)

暂时,让我们忘记颜色。所以问题更简单:计算增加子序列的数量。这个问题有一个标准的解决方案:
1.将每个值映射到[0...n - 1]范围 2.假设f[value]是将value作为最后一个元素的增加子序列的数量。
3.最初,f填充0 4.之后,您从左到右迭代所有数组元素并执行以下操作:f[value] += 1 + get_sum(0, value - 1)(这意味着您将此元素添加到所有可能的子序列,以便它们保持严格增加),其中{{1 }}是数组的当前元素,value返回get_sum(a, b)的总和 答案是f[a] + f[a + 1] + ... + f[b] 使用二进制索引树(又名Fenwick树),可以在f[0] + f[1] + ... + f[n - 1]中执行get_sum操作并获得O(log n)总时间复杂度。

现在让我们回到最初的问题。要考虑颜色,我们可以计算O(n log n)而不是f[value, mask](即,f[value]作为最后一个元素的增加子序列的数量和value(它是一个位掩码,显示哪些颜色存在)颜色)。然后每个元素的更新如下所示:

mask

答案是for mask in [0...2^K - 1]: f[value, mask or 2^(color[i] - 1)] += 1 + get_sum(0, value - 1, mask)

您可以使用与更简单问题相同的想法维护f[0, 2^K - 1] + f[1, 2^K - 1] + ... + f[n - 1, 2^K - 1]二进制索引树以实现2^K时间复杂度。