poj 3279 Fliptile(DFS)

传送门

题意:给一个n\times n的网格(n\le 15),每个格子的颜色为0或1,每次操作会使自身以及上下左右四个相邻的格子的颜色翻转。问最少翻转几次可以使网格全为0。如果无法实现则输出impossible。

题解第一段转自:https://www.cnblogs.com/caitian/p/5396946.html

“如果从上到下搜索,当前行是否需要反转取决于上一行的状态,通过翻转当前行使上一行为0,而不是通过上一行翻转为0后,看当前行的状态判断自己是否需要翻转,否则还会继续影响上一行。所以枚举一下第一行所有的状态,搜索到最后一行结束,如果可以保证最后一行都是0,那么方案可以,否则重新定义第一行的状态,继续搜索,找出使反转次数最少的方案。”

 

现在假设possible,为什么这个方法能求到最优解?
反转次数最少的方案中每个点最多翻转一次。如果我们把反转次数最少的方案翻过的点按照所在行数从小往大翻,一定可以满足:随着过程进行,第一行有0有1,之后第一行全为0,之后前两行全为0......之后前n-1行都为0,最后所有格子都为0,而这个过程模拟的正是题解给出的方法。

 

再细品一下,这样为什么可以判impossible?

最后一行都是0显然说明方案可以,但为什么前面n-1行都为0且最后一行存在1就不行?因为这种状态下,无论怎么翻转,得到的状态始终属于下面两种状态中的一种:

1. 前面n-1行不全为0

2. 最后一行不全为0

而这两种状态都不合法,所以前面n-1行都为0且最后一行存在1的状态是impossible。假设状态cur和状态nxt可以通过翻转互相变成对方,那么它们要么都possible要么都impossible。既然前面n-1行都为0且最后一行存在1的状态是impossible,它又可以由初始状态翻转若干次得到,那么初始状态也是impossible。

你可能感兴趣的:(思维,DFS,思维,DFS)