回溯的实质是在问题的解空间进行深度优先搜索。DFS是个图的算法,但是回溯算法中的图在哪里呢?我们把解空间中的一个解状态当成一个节点,由于解空间非常庞大,所以这个图也就大到无法想象了。
举个例子吧,比如全排列问题,对于n个元素进行全排列,一共有n!种可能,比如n=9时,一共有9! = 362880种排列。初始化,我们什么都没有,定义如下状态
#define PT_SIZE 9
class PTState
{
int m_solution[PT_SIZE];
int m_arranged;
};
其中m_arranged表示已经在m_solution中排列的数字,刚开始时啥都没做,当然是m_arranged为0啦,而m_solution这个数组是用来放要排列的数字的,比如
123456789对应于m_solution[i] = i + 1
那么接下来要做啥呢?当然是开始排第一个数了,也就是要填m_solution[0]啦,这时你有多少种选择呢?嗯,当然是1, 2, 3, 4, 5 ,6, 7,8,9种,这还要说吗?那么先尝试谁呢?
从小到小依次填好了。
下面这个图是n=3时的解空间搜索图,其中白色的节点是初始节点,一个数都没填,第一行全是问号,第二行有个标记,表示还没有排列一个数。当第一位选1的时,节点变成了紫色,此时m_arranged = 1, 还剩两个数没有填。这时填第二个数时&#