通过贪婪算法找到最小移动次数
finding the min number of moves by greedy algorithm
有一个二维网格,其中包含随机单元格中的巧克力。一举一动,我可以把一行或一列中包含的所有巧克力都拿走。拿走所有巧克力所需的最小动作次数是多少?
示例:包含巧克力的单元格是:
0 0
1 1
2 2
最小移动次数 =3
0 0
1 0
0 1
最小移动次数=2
我想这个问题有一个贪婪的算法解决方案。但是如何处理这个问题呢?
我认为这是经典的集合封面问题的变体,它被证明是NP困难的。
因此,贪婪算法只能得到近似值,而不能得到最优解。
对于这个特定问题,它不是NP难的。它可以在多项式时间内求解。解决方案如下:
将 2D 网格转换为二分图。左侧包含表示行的节点,右侧包含表示列的节点。对于每个包含巧克力的单元格,假设它的坐标是 (x,y),添加一个链接row_x和column_y的边。二分图建立后,使用匈牙利算法获得最大匹配。由于在二分图中,最大匹配的答案等于最小顶点覆盖,因此答案正是您想要的。
匈牙利算法是一种 O(V*E) 算法。有关更多详细信息,请参阅匈牙利算法
有关二分图的更多信息,请参考二分图,您可以在此处找到为什么最大匹配等于最小顶点覆盖。
PS:这既不是贪婪的问题,也不是动态编程的问题。这是一个图形问题。
相关文章:
- 将对象移动到std::shared_ptr
- 何时在引用或唯一指针上使用移动语义
- 如何从具有移动语义的类对象中生成共享指针
- 将shared_ptr移动到<StructA>shared_ptr<变体<结构A、结构 B>>
- C / C++ 移位/偏移/向左或向右移动位图?
- MSVC将仅移动结构参数解释为指针
- 自定义先决条件对移动分配运算符有效吗
- 返回值优化:显式移动还是隐式
- 当有分配器意识的容器被复制/移动时,反弹分配器是否被复制/移走
- 为什么复制而不是移动数据元素?
- 可以使用移动语义更改或改进此C++代码吗?
- 使lambda不可复制/不可移动
- c++在使用指针时移动语义
- 将QGraphicsItem的移动区域限制在多边形区域内
- SendInput()鼠标移动计算
- 按值 C++ 返回时进行双倍移动
- 移动二维数组中的字符
- 为什么不调用移动构造函数?(默认情况下只有构造器,没有别的)
- 安全到标准:移动会员?
- 通过贪婪算法找到最小移动次数