如果发现广告等破坏行为,请尽量将条目恢复到较早的版本而不是把相应内容直接删除,谢谢合作。

URAL/1589

来自"NOCOW"

跳转到: 导航, 搜索

这是Ural上的一个经典难题,提交次数 2000多次,AC人数目前只有 6

个,通过率不到 1% !

   首先,先分析一下这个题的数据范围,圈墙,所以实际面积最多只有 6*6,也就是说箱子的个数最多也就 35。 
       ########           ########           ######## 
       #$       $#        #....     #        #   .     # 
       #.       .#        #   $$    #        #        $# 
       #     @    #       #   $$    #        #.        # 
       #.       .#        #         #        #     @   # 
       #$       $#        #     @   #        #   $     # 
       ########           ########           ######## 
   接着是确定搜索的方法,因为是多个箱子,所以为了方便写,只好一步推 

一个箱子,直到所有的箱子都归位。但是这样很容易出现的一个局面就是死锁。

比如一个箱子推到了墙角,4个箱子相互靠在了一起,一个箱子贴在了没有目

标点的一边墙上等等。

   当然死锁远远不止这些,有些人一眼就能看出来,但电脑却不一定了,而 

且频繁地判断死锁会降低程序的效率。既然正想比较麻烦,不如反向思考,将

推箱子变成拉箱子,这样就不会出现上诉的种种死锁了,一步就解决的问题。

于是通过将推箱子变成拉箱子,第一个程序就出来了,同时,为了加速,我用

上了hash,我用他跑了一下几组数据,基本没出解,不过样例过了。而且

键部分还没出来呢。

   这里我们定义一个局面S(P,Q,pos),P为箱子的集合,Q为目标点的 

集合,pos 为当前人的位置。因为是写迭代加深,所以自然而然的想到了估价。

通过迭代加深,我们枚举答案上限MAX,设到当前局面的代价是g,如果g

+h>MAX,便可以剪枝,从而大大提高效率。

   对于估价函数,一个较显然的结论是,点(x1,y1)到点(x2,y2)的花费 

至少是他们的曼哈顿距离|x1-x2|+|y1-y2|,那么我们设计估价h(s)为:

            h(s)=∑min{|Xi-Xj|+|Yi-Yj|,j∈Q},i∈P 
                                                         4 
   这样的估价效果如何呢?这里我选了33组数据进行测试: 
test            生成节点                test              生成节点 
0*    3 3 3 597 5360 23115...       17    3 44 5935 5703 
1     4 4 4 185 34                  18    3 176 421 164 
2     3 43 69                       19    8 233 56 

4 打*表示最终没有跑出解来 题目保证n,m≤8,去掉外边的一

个人工具