我有一个我感兴趣的问题(编程竞赛),我无法判断它是否比我的解决方案更有效。
问题是这样的:
鲍勃是狼人。在他的“狼形态”中,鲍勃的跑得更快 他可以是正常的,人的形式。但是,他能够打开门 作为一个人(由于他的手)更快。他也需要一些金额 来回转换的时间。
如果鲍勃正在追逐某人,他需要沿着走廊旅行 有了门,他想知道最快的方法是什么。
作为一只狼,他每秒跑10米,而他只能跑4米 通常为每秒米。鲍勃需要8秒才能打开一扇门 狼的形态,通常只有1秒。他需要5秒钟 转变为狼形态。
任务是编写一个程序,考虑到走廊的距离 鲍勃需要旅行,以及所有门的位置 走廊,他可以覆盖距离的最短时间,以及如何 他会做出很多改变。
鲍勃总是以人的形式开始。
我解决它的方法是基本遍历可能解决方案的整个空间,并找到成本最低的解决方案。
我觉得可能有一个更简单的贪婪算法来解决这个问题,但我还没有能够找到它。有什么想法吗?
答案 0 :(得分:8)
我的第一个想法是将此视为图搜索问题,您可以使用Dijkstra's algorithm。考虑一下这个图:
door door
HUMAN START-o---------o----o----------o----o-----------------o
| | | | | } END
WEREWOLF o---------o----o----------o----o-----------------o
基本上,在任何给定节点,您都有状态感(距离,isWolf),并且在任何两个节点之间您都有一定的成本(时间)。使用Dijkstra算法,你可以找到任何给定节点的最短时间,有两个可能的结束节点。
正如评论中所指出的那样,你可能会看到图表是针对的:你可能只会向右移动,只有在门和门后的狼变为人类才有意义。
因为这个问题很好地分解为迭代子问题,你可能会从dynamic programming的角度来考虑它,子问题是"到最远端的最快时间是什么? {1}},作为一个人或狼,从door[n]
的远端给出两次?"
(我不会将这些算法中的任何一种称为贪婪,因为你在任何特定时刻都有两种不同的选择,而不仅仅是基于单一最佳解决方案进行开发。总是一个任何给定点的最快方式,但取决于走廊的形状,鲍勃可能有一个尚未知的优势,在运行的其余部分以一种形式或另一种形式。)
答案 1 :(得分:3)
我认为这可以归结为Shortest Path。每个门的图中有2组节点,一个是狼,一个是人。门之间的距离是边缘重量。您可以付费从狼形态过渡(从狼图到人类图)。包括变换在内的两个位置之间的最短路径将对应于组合图中的最短路径。您开始在门上或“人体图”上的特殊起始节点上初始化,并作为狼人在终端节点上完成。
答案 2 :(得分:1)
我不打算做数学所以你必须弄清楚细节,但这是我的想法:
您只能通过以下方式节省时间:
从狼转向人类开门
打开门后,从人类转向狼,跑了一段距离
基本上你只需要在门口之前和之后做出决定。
如果你是一个人,当你打门,穿过门(总是更快)
如果你是一只狼,当你打门时,检查下一个走廊是否足够短,以至于你想在进门之前变成人类
如果你像人一样穿过一扇门,检查你是否应该在走远之前变成一只狼
如果你像狼一样经过一扇门,你应该永远呆在隔壁的门前
祝你好运!答案 3 :(得分:1)
似乎贪婪的解决方案会首先查看最短/最长的运行,决定使用哪种形式,然后用最方便的形式填写其余的。
总的来说,似乎你可以预先计算状态转换,为每个门把手排序,并为每个门把手选择最低值。或者类似的东西,无论如何。
可能类似于操作系统中混合I / O和CPU绑定进程的任务调度,但不幸的是,我无法找到一个很好的研究示例。