解决问题的第一步是了解如何遍历矩阵。下图显示了从起点到其他点的距离。
请注意,等距点排列在对角线上。给定一个set
(叫它A)代表一条对角线,下一条对角线上的点(称之为B) 的发现如下:
for each point in set A
if the x coordinate is greater than zero
add (x-1, y) to set B
if the y coordinate is greater than zero
add (x, y-1) to set B
在示例中,表示对角线的集合应如下所示:
[(2, 2)] // starting position
[(1, 2), (2, 1)] // after 1 move
[(2, 0), (1, 1), (0, 2)] // after 2 moves
[(0, 1), (1, 0)] // after 3 moves
[(0, 0)] // after 4 moves
下图显示了可以使用多少条不同的路径来到达矩阵中的每个点。路径数与中的数字相同帕斯卡三角形。就这个问题而言,唯一重要的是数字增长很快,因此我们需要减少计数。
为了减少路径计数,我们需要在遍历矩阵时剔除非生产性路径。这是通过比较元组来完成的,其中每个元组都包含食物和水。一个元组(F,W)
支配一个元组(f,w)
iff F >= f
AND W >= w
.
例如,考虑矩阵中的中心位置。我们可以通过先向上然后向左移动,或者先向左然后向上移动来到达该点。先向上再向左移动的产量(食物、水)为(3,5),而先向左然后向上移动的产量(3,6)。 (3,6)支配(3,5),所以我们只需要考虑(3,6)。所以经过两次移动之后,我们就出现了下图所示的情况。请注意,我们在中心位置只有 1 个元组,而不是帕斯卡三角形预测的两个元组。
经过三步后,我们得到如下所示的情况。第三对角线上的每个点都有两个元组。这是必要的,因为其中一个元组有更多的食物,另一个元组有更多的水,所以两个元组都不会支配另一个元组。
经过四次移动后,我们有四种可能的答案,选择最好的只是一个简单的比较问题min(food, water)
对于每个元组。