如何解决问题“ 4967-Tri graphs” ICPC Live存档

时间:2019-09-18 04:25:00

标签: algorithm breadth-first-search acm-icpc

首先,我很抱歉我的英语不是很好!!! 这是解决该问题的链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2968

简要说明:找到从图顶部的中间节点到图底部的中间节点的最小成本。

路径的成本将是它经过的所有节点的总和。 enter image description here

因此,我认为我应该使用LCBFS算法来解决此问题,但是我的算法不够好,因此我的代码被超过了时间限制。这是我的代码:http://codepad.org/lJIYOPon。任何人都可以帮助我优化代码,非常感谢。

1 个答案:

答案 0 :(得分:2)

这是我解决问题的方法(并获得了Accepted):

我使用了自下而上的动态编程方法,这使我能够提出O(n)的时间解决方案,其中O(1)用于存储。

让我们使用动态编程表并计算每个rowcol(即dp[row][col])上节点的最低成本是多少。我们将从最后一行开始,然后进行到第一行(自下而上)。

让“图形”存储在大小为graph的二维数组[n][3]中。

首先,很容易看出如果我们要处理一行(最后一行)会产生什么费用。

  1. dp[0] = graph[n - 1][0] + graph[n - 1][1],因为如果我们在列0处,然后跳转到相邻列(到达目标),则答案将是第一和第二个节点的总和列。

  2. dp[1] = graph[n - 1][1],出于相同的原因。

  3. dp[2] = infinity,因为如果我们位于最后一行的最后一列,我们将无法达到目标。

知道了这一点,现在让我们假设图形中有两行,我们想计算第一行的增量。请注意,答案是第二行。

如果我们在第一行(索引为0),则可以计算另一个dp,将其称为next。为了计算next[1],我们应该首先计算next[2],因为从第一列我们可以到达第二列,我们必须知道next[2]的答案。

  1. next[2] = graph[0][2] + min(dp[1], dp[2]),因为从第一行的第2列开始,我们可以转到下一行到12列。我们已经知道存储在先前计算的dp数组中的下一行的最小值。

  2. next[1] = graph[0][1] + min(next[2], min(dp[0], dp[1], dp[2]))。考虑一下为什么要这样计算。

  3. next[0] = graph[0][0] + min(next[1], min(dp[0], dp[1])

我们可以以相同的方式进行操作,并在一般情况下计算N >= 2的最小值。

请注意,我们只能存储最后三个计算出的值,因为从第i行开始,我们可以进入i + 1,因此我们不必存储整个{ {1}}表,但仅最后一行。这种观察将存储器的复杂性降低到[n][3]

这是我的Java代码(我在阅读输入内容时已省略了该部分):

O(1)