给定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)。
答案 0 :(得分:2)
这种动态编程解决方案在O(nm)
时间内运行,需要O(n)
空间。
首先建立一个名为reachable
的布尔数组,除false
reachable[s]
外,将其初始化为true
。
此数组现在表示是否可以0
步骤访问某个数字。现在,对于i
到1
的每个m
,我们都会更新数组,以便reachable[x]
表示x
步中是否可以访问数字i
。这很简单:只有在x
步骤中可以访问i
或x - 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]
。
如果您想保持可以达到每个号码的方式,那么您可以进行以下更改:
r
更改为整数数组; r[x]
初始化为0
,r[s]
除外1
; 在主循环中,将关键行更改为:
r [x] = last_r [x + A [k]] + last_r [x - A [k]]