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

Max number ways to jump to the last element

本文关键字:最大数 方式 元素 最后一个      更新时间:2023-10-16

我有一个比赛中的问题,想知道答案。

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

您可以在任何位置最多跳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

感谢

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

在这种情况下,到达终点的旅程有三个可能的第一步:一跳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.

与斐波那契递归的相似性并非巧合。这个序列通常被称为"Tribonacci序列",你可以很容易地在常见的地方(mathworld、wikipedia、oeis等)查找它,以找到各种计算技术,包括下面的技术。

很明显,您可以通过从末尾开始并向后工作来计算O(n)中的Tribonacci函数(定义f(0)=1,f(-1)=0,f(-2)=0以提供起始位置。)但使用与O(log n)运算中计算斐波那契数相同的技术,很容易做得更好。

这是斐波那契算法。我们从观察矩阵乘积开始:

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

让我们将F(n)用于第n个斐波那契数,并调用MF之上的1和0的矩阵。我们可以看到

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

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

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

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

    = 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

您知道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数组中记住它)

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

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

由于你最多只能走3步,一旦你知道了这个公式,这真的还不错。实际上,你只是在寻找可以取代输入中1的2和3的组合。我建议从1 3开始,然后通过每个2来填充剩余部分。然后重复2个3秒,以此类推。如果你预先计算并保存所有的阶乘,它应该运行得很快,尽管我相信还有其他优化。