我发现了这个有趣的动态编程问题,并且想知道这种方法。
给我们一个大小为’n’的数组’a’。
数组的每个元素都是“ 1”或“ 2”。
我们从索引‘0’开始。如果a [i] = 1,我们可以转到i + 1或i-1。
相反,如果a [i] = 2,我们可以转到i + 1或i + 2或i-1或i-2。
我们必须找到所有可能路径的数量。
主要约束:-1)我们只能访问一次数组中的特定索引。
2)我们总是从索引‘0’开始。
3)一条路径可以在我们想要的任何时候结束:-)
数组示例:-> [1,1,1,1]
回答:-4
第一条可能路径:[0]
第2条可能的路径:[0,1]
第三种可能的路径:[0,1,2]
第四条可能的路径:[0,1,2,3]
另一个例子 : -
[2,2,2]
答案:-5
路径:-[0],[0,1],[0,1,2],[0,2,1],[0,2]
(此问题分为3部分!)
n的值在范围内:-1)[1,100000]
2) [1,10] 3)[1,1000]
考虑使用的空间。
0 1 2 3 4 5 6 ^
为了从右边获得一个数字,必须使用它之前的单元格。因此,所有以x左边结尾的方式都不能包含右边的数字。而所有方法的最终结果x都来自使用x-1的右侧,以及x从左侧向右侧不相交的一组移动。
x
x-1
设f(A, x) = l(A, x) + r(A, x),其中l(A, x)表示从左侧开始以x结尾的所有方式;r(A, x),来自右边。
f(A, x) = l(A, x) + r(A, x)
l(A, x)
r(A, x)
要获取l(A, x),我们需要:
(1) all ways to reach (x-1) = l(A, x-1) (there are no numbers used to the right of x, and since x is used last, we could not have reached x-1 from the right.) (2) all ways to reach (x-2): cleary we need l(A, x-2). Now to reach (x-2) from the right, the only valid path would have been ...(x-3)->(x-1)->(x-2) which equals the number of ways to reach (x-3) from the left. = l(A, x-2) + l(A, x-3)
要获取r(A, x),我们需要:
(1) all ways to reach (x+1) so as to directly go from there to x = l(A, x-1) (We can only reach (x+1) from (x-1).) (2) all ways to reach (x+2) after starting at (x+1) = l(A, x-1) * f(A[x+1...], 1) (To get to the starting point in A[x+1...], we must first get to (x-1).)
所以看来
f(A, x) = l(A, x) + r(A, x) l(A, x) = l(A, x-1) + l(A, x-2) + l(A, x-3) r(A, x) = l(A, x-1) + l(A, x-1) * f(A[x+1...], 1)
每次我们运行以下JavaScript代码时,它都会尝试使用不同的7元素数组。我将备忘录和优化留给读者(为了有效地制表f(_, 1),请注意l(_, 1) = 1)。
f(_, 1)
l(_, 1) = 1
function f(A, x){ if (x < 0 || x > A.length - 1) return 0 return l(A, x) + r(A, x) function l(A, x){ if (x < 0 || x > A.length - 1) return 0 if (x == 0) return 1 let result = l(A, x-1) if (A[x-2] && A[x-2] == 2){ result += l(A, x-2) if (A[x-3] && A[x-3] == 2) result += l(A, x-3) } return result } function r(A, x){ if (x < 0 || x >= A.length - 1 || !(A[x-1] && A[x-1] == 2)) return 0 let result = l(A, x-1) if (A[x+2] && A[x+2] == 2) result += l(A, x-1) * f(A.slice(x+1), 1) return result } } function validate(A){ let n = A.length function g(i, s){ if (debug) console.log(s) let result = 1 let [a, b] = [i+1, i-1] if (a < n && !s.includes(a)) result += g(a, s.slice().concat(a)) if (b >= 0 && !s.includes(b)) result += g(b, s.slice().concat(b)) if (A[i] == 2){ [a, b] = [i+2, i-2] if (a < n && !s.includes(a)) result += g(a, s.slice().concat(a)) if (b >= 0 && !s.includes(b)) result += g(b, s.slice().concat(b)) } return result } return g(0, [0]) } let debug = false let arr = [] let n = 7 for (let i=0; i<n; i++) arr[i] = Math.ceil(Math.random() * 2) console.log(JSON.stringify(arr)) console.log('') let res = 0 for (let x=0; x<arr.length; x++){ let c = f(arr, x) if (debug) console.log([x, c]) res += c } if (debug) console.log('') let v = validate(arr) if (debug) console.log('') console.log(v) console.log(res)