我们有一组连接成一个圆圈的节点,从一个节点到另一个节点有一个额外的单向连接。指令集由F
组成,顺时针移动一个节点,逆时针移动一个节点B
,以及P
,通过单向连接。
每个节点都有一个到节点的单向连接(可以是自身)。每个连接可以在与其之前的节点的连接相同的节点上进行,或者进一步(节点和连接另一侧的节点具有相同的顺序)。我需要找到可以移动到第一个节点的最短指令集的长度,无论起始节点如何。
我已经尝试寻找以连接到自身的节点结束的连接链,因为它是所有应该收敛的地方,但是在第一次收敛之后我还没有找到任何优化的方法来确定到下一个的最短路径“最佳”融合。我没有在互联网上找到任何关于这个的东西,而且我缺乏想法。我认为这背后有一个数学定理,但我找不到任何数学定理。
我已经查看过最小生成树(Find the minimal common path from any nodes to one node),但由于我有一套说明,因此不适合。
编辑:一个例子。
假设我们有以下数据:0 1 0 0
(这意味着第一个节点的连接前进0个节点,第二个节点前进1个节点,等等)。这可以这样绘制(我省略了每个节点之间的链接):
o--o
| | <------------ Those are "dead" nodes
| V
o--1 2
|
V <--- This is a "convergence chain"
o--4 3--o
| ^ ^ |
| | | |
o--o o--o
此处,解决方案为PBPBPFF
(或PBPBPBB
)。在这里,我们使用汇聚链作为对它们进行分组的方法,然后我们将它们转移到第一个节点。
答案 0 :(得分:0)
让我们假设圆的长度是N.在输入上,我们还有一个数组C [N]。 位置P有三种可能的操作:
a) p = (p - 1) % N
b) p = (p + 1) % N
c) p = (p + C[p]) % N
让我们尝试尝试分解一下这个问题。首先,让我们尝试找到一个将位置P,Q置于同一位置R的链。
我们很快就会发现让两个位置“更接近”彼此不会超过O(N)步。如果我们执行N步并且两个位置仍然处于相同的距离,我们应该使用简单的旋转,这将最多需要N / 2步。 根据这一观察,如果可能,简单的BFS在O(N ^ 2)中找到解。如果在N ^ 2步骤中找不到解,则解决方案不存在。现在,使用此链,移动所有输入位置,选择另外两个并找到它们的解决方案。最后,我们最终得到一个单一的位置,将其转换为初始位置是微不足道的。因此,如果有任何问题的解决方案,该算法将在
找到它O(
N - n positions
*
(N^2 - merge two positions to one
+
N * N^2 - recalculate the positions with chain we've just found
)
)
,最多N ^ 3个命令(每个命令应用N次)。
现在,我们可以简单地BFS一个所有可能组合的图表。
从(“”,[0..n])开始,我们可以循环队列并根据我们的命令推送新的三个项目(如果尚未找到位置):
(commands, [p1, p2, ... pn]) ->
(commands + "F", [(p1 + 1) % N, ... (pn + 1) % N])
(commands + "B", [(p1 - 1) % N, ... (pn - 1) % N])
(commands + "P", [(p1 + C[p1]) % N, ... (pn + C[pn]) % N])
当向量用零填充时,或者如果我们执行了足够的步骤以便找不到解决方案时,我们终止。边界可能会有所改善,但应该清楚这些我提到的工作。