首先,我很抱歉我的英语不是很好!!! 这是解决该问题的链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2968
简要说明:找到从图顶部的中间节点到图底部的中间节点的最小成本。
因此,我认为我应该使用LCBFS算法来解决此问题,但是我的算法不够好,因此我的代码被超过了时间限制。这是我的代码:http://codepad.org/lJIYOPon。任何人都可以帮助我优化代码,非常感谢。
答案 0 :(得分:2)
这是我解决问题的方法(并获得了Accepted
):
我使用了自下而上的动态编程方法,这使我能够提出O(n)
的时间解决方案,其中O(1)
用于存储。
让我们使用动态编程表并计算每个row
和col
(即dp[row][col]
)上节点的最低成本是多少。我们将从最后一行开始,然后进行到第一行(自下而上)。
让“图形”存储在大小为graph
的二维数组[n][3]
中。
首先,很容易看出如果我们要处理一行(最后一行)会产生什么费用。
dp[0] = graph[n - 1][0] + graph[n - 1][1]
,因为如果我们在列0
处,然后跳转到相邻列(到达目标),则答案将是第一和第二个节点的总和列。
dp[1] = graph[n - 1][1]
,出于相同的原因。
dp[2] = infinity
,因为如果我们位于最后一行的最后一列,我们将无法达到目标。
知道了这一点,现在让我们假设图形中有两行,我们想计算第一行的增量。请注意,答案是第二行。
如果我们在第一行(索引为0),则可以计算另一个dp
,将其称为next
。为了计算next[1]
,我们应该首先计算next[2]
,因为从第一列我们可以到达第二列,我们必须知道next[2]
的答案。
next[2] = graph[0][2] + min(dp[1], dp[2])
,因为从第一行的第2
列开始,我们可以转到下一行到1
和2
列。我们已经知道存储在先前计算的dp
数组中的下一行的最小值。
next[1] = graph[0][1] + min(next[2], min(dp[0], dp[1], dp[2]))
。考虑一下为什么要这样计算。
next[0] = graph[0][0] + min(next[1], min(dp[0], dp[1])
我们可以以相同的方式进行操作,并在一般情况下计算N >= 2
的最小值。
请注意,我们只能存储最后三个计算出的值,因为从第i
行开始,我们可以进入i + 1
,因此我们不必存储整个{ {1}}表,但仅最后一行。这种观察将存储器的复杂性降低到[n][3]
!
这是我的Java代码(我在阅读输入内容时已省略了该部分):
O(1)