基本思想:
- 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。
- 回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择。
- 满足回溯条件的某个状态的点称为“回溯点”。
基本步骤:
- 针对所给问题,确定问题的解空间:首先应明确定义问题的解空间,问题的解空间应至少包含问题的一个最优解
- 确定结点的扩展搜索规则
- 以深度优先方式搜索解空间,并在搜索过程中用剪枝函数(① 用约束条件剪除得不到的可行解的子树 ② 用目标函数剪取得不到的最优解的子树)避免无效搜索
例题:
N皇后
#include<iostream>
#include<cstring>
using namespace std;
int a[11];
int n,ans;
void dfs(int cur,int n)
{
int i,j;
if(cur==n) //递归边界
ans++;
else for(i=0;i<n;i++)
{
int ok=1;
a[cur]=i; //尝试把第cur行的皇后放在第i列
for(j=0;j<cur;j++) //检查是否和前面的皇后冲突
if(a[cur]==a[j]||cur+a[cur]==j+a[j]||cur-a[cur]==j-a[j])
{ok=0;break;}
if(ok) dfs(cur+1,n); //如果合法,则继续递归
}
}
int main()
{
int b[11];
for(int i=1;i<=10;i++)
{
ans=0;
dfs(0,i);
b[i]=ans;
}
int m;
while(cin>>m)
{
if(m==0) break;
cout<<b[m]<<endl;
}
return 0;
}