回溯算法

回溯算法

回溯法是一种组织搜索的一般技术,有“通用的解题法”之称,用它可以系统的搜索一个问题的所有解或任一解
应用回溯法求解时,需要明确定义问题的解空间。问题的解空间应至少包含问题的一个(最优)解。
在生成解空间树时,定义以下几个相关概念:
活结点:如果已生成一个结点而它的所有儿子结点还没有全部生成,则这个结点叫做活结点。
扩展结点:当前正在生成其儿子结点的活结点叫扩展结点(正扩展的结点)。
死结点:不再进一步扩展或者其儿子结点已全部生成的结点就是死结点。
在确定了解空间的组织结构后,回溯从开始结点(根结点)出发,以深度优先的方式搜索整个解空间。
这个开始结点成为一个活结点,同时成为当前的扩展结点。在当前的扩展结点,搜索向深度方向进入一个新的结点。这个新结点成为一个新的活结点,并成为当前的扩展结点。
若在当前扩展结点处不能再向深度方向移动,则当前的扩展结点成为死结点,即该活结点成为死结点。此时回溯到最近的一个活结点处,并使得这个活结点成为当前的扩展结点
回溯法以这样的方式递归搜索整个解空间(树),直至满足中止条件。

N皇后问题
在n×n格的棋盘上放置彼此不受攻击的n个皇后。
按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n皇后问题等价于在n×n格的棋盘上放置n个皇后,任何两个皇后不放在同一行或同一列或同一斜线上。
编程要求:找出一个n×n格的棋盘上放置n个皇后并使其不能互相攻击的所有方案。(即不能出现在同一行、同一列、同一斜线上的棋子)
在这里插入图片描述

#include<iostream>
using namespace std;
#define NUM 20
int n;
int x[NUM];
int sum;
inline bool Place(int t)//内联函数
{
	int i;
	for (i = 1; i < t; i++)
		if ((abs(t - i) == abs(x[i] - x[t])) || (x[i] == x[t]))
			return false;
	return true;
}
void Backtrack(int t)
{
	int i;
	//到达叶子结点,获得一个可行方案。累计总数,并输出该方案
	if (t > n)
	{
		sum++;		//是全局变量
		for (i = 1; i <= n; i++)
			cout << x[i];
		cout << "\n";
	}
	else
		for (i = 1; i <= n; i++)
		{
			x[t] = i;
			if (Place(t)) Backtrack(t + 1);
		}
}
int main()
{
	cin >> n;
	Backtrack(1);
	cout << sum << endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值