我有一个比赛的问题,想知道解决方案。
问题是关于查找跳转到最后一个元素的唯一方式的最大数量。我正在考虑使用动态编程的解决方案,但无法弄明白。
您可以在任何位置跳过最多 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
谢谢
答案 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,依此类推。如果您预先计算并保存所有因子,它应该运行得非常快,但我确定还有其他优化。