我们有一条长度为N的路径。我们只能采取单位步骤。我们有多少种方式可以在保持在路径中的同时采取K步骤。最初我们处于第0位。 例子N = 5
|---|---|---|---|---|
0 1 2 3 4 5
如果k = 3,那么我们就像 -
一样移动0->1->2->1
0->1->0->1
0->1->2->3
您能否就如何解决此问题提供一些指示/链接?
答案 0 :(得分:3)
使用组合方法而不是计算方法可能是可以解决的。但是既然你在询问stackoverflow,我认为你需要一个计算解决方案。
有一个递归关系定义以i
结尾的路径数:
P[N, 0, i] = 1 if i==0 otherwise 0
P[N, K, i] = 0 if i<0 or i>N
P[N, K, i] = P[N, K-1, i-1] + P[N, K-1, i+1]
对于P[N, K, i]
的数组i=0..N
,我们可以针对给定K
迭代计算P[N, K-1, i]
的{{1}}数组。
这是一些执行此操作的Python代码。它使用了一个小技巧,即在数组末尾增加i=0..N
,以便0
和r[-1]
都为零。
r[N+1]
这在O(NK)时间运行。
一个不同的(但相关的)解决方案是让def paths(N, K):
r = [1] + [0] * (N+1)
for _ in xrange(K):
r = [r[i-1]+r[i+1] for i in xrange(N+1)] + [0]
return sum(r)
print paths(5, 3)
为(N + 1)个(N + 1)矩阵,由位置(i + 1,i)和(i,i +)的1组成1)对于i = 0..N + 1,0在其他地方 - 也就是说,在对角线和超对角线上是1。然后M
(即M^K
提升到M
次幂)包含位置(i,j)从K
到i
的路径数在j
步骤。因此K
是从长度为sum(M^K[0,i] for i=0..N)
的0开始的所有路径的总数。这在O(N ^ 3logK)时间内运行,因此仅当K
远大于K
时才优于迭代方法。
答案 1 :(得分:0)
接受答案中第一种方法的Java实现 -
for (int i = 0; i <= K; i++) {
for (int j = 1; j <= N; j++) {
if (i > 0)
dp1[i][j] = (dp1[i - 1][j - 1] + dp1[i - 1][j + 1]) % 1000000007;
else
dp1[i][j] = 1;
}
}
System.out.println(dp1[K][N-1])
复杂度O(KN)
Java DP实现,它计算所有起始位置和值1-N和1-K的答案 -
for (int i = 0; i <= K; i++) {
for (int j = 1; j <= N; j++) {
for (int k = 1; k <= j; k++) {
if (i > 0)
dp[k][j][i] =
(dp[k - 1][j][i - 1] + dp[k + 1][j][i - 1]) % 1000000007;
else
dp[k][j][i] = 1;
}
}
}
System.out.println(dp[1][5][3]);
O(KN ^ 2)