如何从某个位置查找所有可能的可到达号码?

时间:2016-05-14 16:18:58

标签: algorithm data-structures dynamic-programming

给定2 elements n, s and an array A of size m,其中s is initial position位于1 <= s <= n之间,我们的任务是对s执行m次操作,并且在每次操作中我们要么使s = s + A [i]或s = s - A [i],我们必须打印m操作后可能的所有值,所有这些值应介于1 - n(含)之间。

  

重要说明:如果在操作期间我们得到一个值s&lt; 1或s> N,   我们不再追求s的价值。

我使用BFS解决了这个问题,但问题是BFS方法在这里不是最优的,有人可以向我建议任何其他更优化的方法,或者算法会有很大的帮助。

例如: -

如果n = 3,则s = 3,并且A = {1,1,1}

                            3
                         /     \
operation 1:           2         4  (we don’t proceed with 4 as it is > n)
                   /   \         /  \
operation 2:     1       3      3    5
                / \     / \    / \   / \
operation 3:   0   2   2   4  2   4  4  6

因此遵循上述规则可达到的最终值是2和2(即2倍2)。我们不考虑第三个,因为它有一个中间状态,即&gt; n(同样适用,如果&lt; 1)。

1 个答案:

答案 0 :(得分:2)

这种动态编程解决方案在O(nm)时间内运行,需要O(n)空间。

首先建立一个名为reachable的布尔数组,除false reachable[s]外,将其初始化为true

此数组现在表示是否可以0步骤访问某个数字。现在,对于i1的每个m,我们都会更新数组,以便reachable[x]表示x步中是否可以访问数字i 。这很简单:只有在x步骤中可以访问ix - A[i]时,x + A[i]步骤才能i - 1

最后,数组成为您想要的最终结果。

编辑:这里是伪代码。

// initialization:
for x = 1 to n:
    r[x] = false
r[s] = true

// main loop:
for k = 1 to m:
    for x = 1 to n:
        last_r[x] = r[x]
    for x = 1 to n:
        r[x] = (last_r[x + A[k]] or last_r[x - A[k]])

如果last_r[x]不在false范围内,则x符合惯例[1 .. n]

如果您想保持可以达到每个号码的方式,那么您可以进行以下更改:

  1. 将数组r更改为整数数组;
  2. 在初始化过程中,将所有r[x]初始化为0r[s]除外1;
  3. 在主循环中,将关键行更改为:

    r [x] = last_r [x + A [k]] + last_r [x - A [k]]