我试图解决这个问题有点困难。造成混淆的主要原因是不知道何时拆除箱子。
这是我的方法:
我逐列查看容器列。如果原点框的最顶部框是空的并且目标框不为空,那么我知道要添加该框。我知道如果反之亦然,将移除顶盒。我认为当两个位置都有一个盒子但是不同时我必须交换。但是我的问题是在某些情况下,在底部移除一个盒子会使一切都向下移动并使其更像目的地盒子。或者可以在中心移除一个或移除两个,一个在底部,一个在中心。我如何知道何时取出盒子?我可以删除所有组合,看看哪个组合最接近目的地,但这似乎效率不高。
我也许认为这是一个明显的动态编程问题。任何帮助将不胜感激
答案 0 :(得分:1)
您已经将问题简化为一次考虑一个列,所以让我们从此开始。
不要考虑列中可能发生的特定操作,而是让我们一般地看一下这个过程。 最初,我们有给定的列。 最后,我们得到了结果列。 结果列中给定列的左边是什么? 这是一个子序列(因为我们可以从任何地方删除一个框),它转移到结果列的前缀("前缀"就像在#34;位于底部",因为我们只能在最初的东西之上添加新的盒子。
当然,我们希望最大化此序列的长度(子序列或前缀,具体取决于您查看的位置)。 这确实看起来像动态编程问题,类似于edit distance或longest common subsequence。 也许你会想从这一点自己解决细节问题。 祝你好运!
答案 1 :(得分:1)
您当然可以一次处理一列。
然后,要将列[x1, x2, x3, ...]
转换为列[y1, y2, y3, ...]
,您会遇到以下几种情况:
x1
与y1
相同:这是一个简单的案例,您需要与其他案例相匹配x1
为-
且y1
不是:您需要插入所有剩余的y
框y1
为-
且x1
不是:您需要删除所有剩余的x
框x1
和y1
不是空的,而是不同的;在这里你必须选择:(D1)翻转x1
并将[x2,...]
与[y2,...]
匹配,(D2)删除x1
并将[x2, ...]
与{{1}匹配}}。您应该选择(D1)或(D2),具体取决于哪一项需要较少的操作。注意:在[y1, ...]
中插入y1
并将x
与[x1,...]
匹配的选项(D3)在规则中不可用,因为您只能在堆顶(案例B)。
这可以转换为动态编程(或带记忆的递归)算法:
[y2,...]
并且您需要计算将列int min_moves(int i, int j);
与列x[i], x[i+1], ...
对齐的移动次数,其中y[j], y[j+1], ...
和x
是从中读取的两个清单的原始内容文件,假设y
和x[i]
为y[i]
-
。
要计算i>m
,您可以使用min_moves(i, j)
(案例A + D1),min_moves(i+1, j+1)
(案例D2)。案例B和C不需要递归,但可以直接计算min_moves(i+1, j)
和x
。