问题陈述: 我们有一个m * n矩阵。起点是左上方的单元格。我们只能在矩阵中向下或向右移动。在矩阵中随机选择目的地。现在我们需要找到具有以下约束的最佳例程:
与其在左侧使用例程,不如在右侧使用例程。
在下面的示例中,与其选择左手边的解决方案,不如选择右手边的解决方案,因为它通过从(2,0)向下移动1而不是右手向下移动到(2,1) 2(0,1)。
其他示例如下所示,都是最佳例程。
我正在为此工作一段时间。我研究了一些算法,例如传递性约简和Dijkstra,但没有弄清楚。如果您想给我一些有关算法的提示,那将是很棒的。
谢谢!
编辑2:
我已经收到有关Dijkstra算法和使用动态编程的一些想法。我认为对于Dijkstra算法,如果您可以提供一些提示,可以将这个问题转换为一个很好的图形问题。我一直在研究算法,认为它的主要问题是不必访问单元格。在下面的示例中,如果我们删除目的地之一,则与左侧地图相比,整个例程将发生重大变化。
对于动态编程,我对节点应如何连接到路径有一个想法。优先级应如下:
但是问题在于它无法通过动态视图来考虑问题,这将输出错误的结果。
答案 0 :(得分:1)
我认为您的示例都可以使用以下通用算法:从第一行和第一列的末尾开始,然后从第二行和第二列的末尾开始,等等,同时向左和向上遍历-从每个D
遇到最接近的路线D
或S
(当然,沿N-NW-W弧线的曼哈顿距离)。
示例7:
1 2 3 4
1 S D
2 D
3 D
4 D D
1 2 3 4
1 S-----D<
|
2 | D
|
3 | D
|
4 D D
^
1 2 3 4
1 S-----D
| |
2 | D <
|
3 |-D
|
4 D D
^
1 2 3 4
1 S-----D
| |
2 | D
|
3 |-D
|
4 D-----D<
^
示例5:
1 2 3 4
1 S
2 D
3 D
4 D D
1 2 3 4
1 S <
|
2 | D
|
3 | D
|
4 D D
^
1 2 3 4
1 S
|
2 |-----D<
|
3 | D
|
4 D D
^
1 2 3 4
1 S
|
2 |-----D
| |
3 | D <
|
4 D D
^
1 2 3 4
1 S
|
2 |-----D
| |
3 | D--
| |
4 D D<
^
示例1:
1 2 3 4
1 S
2 D
3 D D
4 D
1 2 3 4
1 S--
|
2 --D <
|
3 D D
4 D
^
1 2 3 4
1 S--
|
2 --D
|
3 D---D<
|
4 D
^
答案 1 :(得分:0)
这是一个递归问题。您应该尝试练习贪婪算法和动态编程,并尝试进行一些分类以及一些混合编程问题,以更好地了解何时以及如何应用制作两者结合的算法。
使用分而治之方法来解决此问题。将自己放在移动光标的位置,然后考虑可以在每个节点上执行的一组有序逻辑操作,以解决问题。
几天后,我将添加我的算法来解决此问题。这是为了确保我不会意外地帮助某人在比赛中发热量。
您可以参考this和this来对该技术有所了解。 我还发现了一个有趣的article与更好地了解递归有关。它可能不会提供很多信息,但是绝对是激励人的。
提示: 只有3个可能的地方可以找到未访问的目标节点,以便可以访问:
一种可能的算法是您递归:
[编辑1:对不起,我忘了提到默认情况!!]
答案 2 :(得分:0)
感谢您的所有回答和评论。所有这些评论对我都很有价值,并激发了我的思维。
我现在想出一个利用现有Dijkstra算法和正确的节点遍历顺序的解决方案。现在,我们不再从左上角开始,而是将原始源作为目标。然后将所有方向都向后转,以便现在我们只能从一个节点向左或向上移动。解决方案如下所示:
构建加权图。所有左上边缘的权重为1,所有上边缘的权重为(m +1-col),因此上移例程的第一列(具有4 x 4矩阵)的权重均为5。重量图示例如下所示:
将节点(0,0)添加到已建立的路由。
从左上角的节点(0,0)开始,检查其右侧的所有节点((0,0)至(0,n))。然后检查其底部的所有节点((1,0)至(m,0))。对于所有“源”节点(最初是目标节点),请使用Dijkstra算法找到返回“ 已建立路由”的最短路径,然后将Dijkstra算法中的所有节点添加到已建立路由中。
对所有节点(i,i)重复步骤3,直到最后一个节点((m,m)或(n,n))。
任何其他更有效的解决方案都将受到欢迎。另外,如果您发现此算法存在一个陷阱,那就太好了。该算法似乎有效,但是我感觉这不是最有效的方法。