跳转到最后一个元素的最大数字方式

时间:2014-09-18 13:22:01

标签: c++ arrays algorithm dynamic-programming

我有一个比赛的问题,想知道解决方案。

问题是关于查找跳转到最后一个元素的唯一方式的最大数量。我正在考虑使用动态编程的解决方案,但无法弄明白。

您可以在任何位置跳过最多 3个步骤。步数将以n给出,我们的程序应计算最大跳转次数以达到n+1位置。

例如: n = 4,跳到n + 1位置的最大跳数应为7

Jump1: 1 2 1    
Jump2: 1 1 2    
Jump3: 2 1 1    
Jump4: 1 3    
Jump5: 3 1    
Jump6: 2 2    
Jump7: 1 1 1 1

谢谢

3 个答案:

答案 0 :(得分:3)

这句谚语说,最长的旅程始于一步。

在这种情况下,到达目的地的过程中有三个可能的第一步:跳跃1或2或3个点。在每种情况下,旅程将从更近的点继续,更接近结束的1,2或3步。因此,如果我们知道来自较近点的可能路径的数量,我们可以简单地添加它们:

paths(n) = paths(n-1)   // First hop was one,   n-1 elements left
         + paths(n-2)   // First hop was two,   n-2 elements left
         + paths(n-3)   // First hop was three, n-3 elements left.

与Fibonacci递归的相似性并非巧合。这个序列通常被称为“Tribonacci序列”,您可以在通常的地方(mathworld,wikipedia,oeis等)轻松查找,以找到各种计算技术,包括下面的计算技术。

显然,您可以通过从结尾开始并向后工作来计算O(n)中的Tribonacci函数(定义f(0)= 1,f(-1)= 0,f(-2)= 0到提供一个起始位置。)但是,使用可用于在O(log n)操作中计算斐波纳契数的相同技术,可以很容易地做到这一点。

这是Fibonacci算法。我们首先观察矩阵乘积:

          | 1  1 |
[ a b ] x |      |  = [ a+b a ]
          | 1  0 |

让我们使用F(n)作为n th Fibonacci数,并调用高于MF的1和0的矩阵。我们可以看到

[ F(n) F(n-1) ] = [ 1 0 ] × MF × MF × … × MF
                              n products

但由于矩阵乘法是关联的,我们可以将其重写为:

[ F(n) F(n-1) ] = [ 1 0 ] × MFn

同样,由于矩阵乘法是关联的,我们可以在MFn步骤中计算O(log N)。例如,我们可以使用递归:

    = Mn/2 × Mn/2 if n is even
Mn
    = M × M(n-1)/2 × M(n-1)/2 if n is odd

同样,对于Tribonacci数字T(n),我们可以定义矩阵MT

     | 1 1 0 |
MT = | 1 0 1 |
     | 1 0 0 |

并采用与上述相同的逻辑:

[ T(n) T(n-1) T(n-2) ] = [ 1 0 0 ] × MTn

答案 1 :(得分:2)

你知道n = 0,n = 1和n = 2的方法的数量吗?

对于任何较大的值N,路数= number of ways for N - 1 + number of ways for N - 2 + number of ways for N - 3

您不应该计算给定n超过1次的方式的数量。 (记住它在dp数组中)

答案 2 :(得分:0)

重要的功能是(number_of_elements)!/product((number_repeated_characters)!)

例如,如果你知道2211是你的一条路径,那么4!/ 2!* 2!因此,对于2" 2" s和2" 1" s有6个路径组合。

由于你只需要最多3步,所以一旦你知道这个公式,它真的不会太糟糕。真的,您只是在寻找能够取代输入中的1的2和3的组合。我建议从1 3开始,然后通过每个2填充剩余部分。然后重复2 3s,依此类推。如果您预先计算并保存所有因子,它应该运行得非常快,但我确定还有其他优化。