通过贪婪算法找到最小移动数

时间:2013-10-08 06:36:31

标签: c++ dynamic-programming memoization greedy

有一个2-d网格,其中包含随机单元格中的巧克力。一次,我可以将所有巧克力包含在一行或一列中。取出所有巧克力所需的最小移动次数是多少?

示例:含有巧克力的细胞是:

0 0
1 1
2 2

分钟。没有移动= 3

0 0
1 0
0 1

min no of moves = 2

我想这个问题有一个贪婪的算法解决方案。但是如何解决这个问题呢?

2 个答案:

答案 0 :(得分:0)

我认为这是经典Set Cover问题的一个变化,被证明是NP难的。

因此,贪婪算法只能得到近似值而不是最优解。

答案 1 :(得分:0)

对于这个具体问题,它不是NP难的。它可以在多项式时间内求解。解决方案如下:

将2D网格转换为二分图。左侧包含节点表示行,右侧包含节点表示列。对于每个包含巧克力的单元格,假设它的坐标是(x,y),添加一个链接row_x和column_y的边。建立二分图后,使用匈牙利算法获得最大匹配。因为在二分图中,最大匹配的答案等于最小顶点覆盖,答案正是你想要的。

匈牙利算法是O(V * E)算法。有关详细信息,请参阅Hungarian algorithm

有关二分图的更多信息,请参阅Bipartite graph,您可以找到为什么最大匹配等于此处覆盖的最小顶点。

PS:它既不是贪婪问题,也不是动态编程问题。这是一个图形问题。