回溯法的两种框架:递归回溯与迭代回溯

递归回溯:

private static void backtrack(int t){
    if t>=n then                          //递归深度t大于等于最大层次n,输出解向量x
        output(x)
    for j<-f(n,t) to g(n,t) do            //f(n,t)为子树的起始编号,g(n,t)为子树的终止编号
        x[t]<-value(i)                    //将当前拓展节点x[t]赋上所选子树的值
        if constraint(t)&&bound(t) then   //constraint(t)约束函数、bound(t)界函数
            backtrack(t+1)
}

迭代回溯:

void iterativeBacktrack ()
{
	t=1;
	while t>0 then
		if f(n,t)<=g(n,t) then                //当前是否还有节点可选
		    for i<-f(n,t) to g(n,t) do        //遍历所有节点
                x[t]<-value(i)
				if constraint(t)&&bound(t) then
					if solution(t) then
                        output(x)
					else
                        t++
		else
            t--
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C++ 回溯法解决 N 皇后问题,可以使用递归迭代两种方法实现。 首先,我们需要定义一个二维数组表示棋盘,初始化为0表示该位置没有皇后。然后,我们从第一行开始逐行放置皇后,对于每一行,我们需要检查该行的每一列是否可以放置皇后,如果可以,则在该位置放置皇后,并递归进入下一行;如果不行,则回溯到上一行,继续尝试其他列。 1. 递归解法 ``` #include <iostream> using namespace std; const int N = 10; int ans = 0; int board[N][N]; void dfs(int row) { if (row == N) { ans++; return; } for (int col = 0; col < N; col++) { bool flag = true; for (int i = 0; i < row; i++) { if (board[i][col] || (col - row + i >= 0 && board[i][col - row + i]) || (col + row - i < N && board[i][col + row - i])) { flag = false; break; } } if (flag) { board[row][col] = 1; dfs(row + 1); board[row][col] = 0; } } } int main() { dfs(0); cout << ans << endl; return 0; } ``` 2. 迭代解法 ``` #include <iostream> #include <stack> using namespace std; const int N = 10; int ans = 0; int board[N][N]; struct Node { int row; int col; int state; Node(int i, int j, int s): row(i), col(j), state(s) {} }; void dfs() { stack<Node> s; s.push(Node(0, 0, 0)); while (!s.empty()) { Node node = s.top(); s.pop(); int row = node.row; int col = node.col; int state = node.state; if (row == N) { ans++; continue; } if (state == 0) { // 第一次访问节点 for (int c = 0; c < N; c++) { bool flag = true; for (int i = 0; i < row; i++) { if (board[i][c] || (c - row + i >= 0 && board[i][c - row + i]) || (c + row - i < N && board[i][c + row - i])) { flag = false; break; } } if (flag) { s.push(Node(row, col, 1)); s.push(Node(row + 1, c, 0)); board[row][c] = 1; break; } } } else { // 第二次访问节点 board[row][col] = 0; } } } int main() { dfs(); cout << ans << endl; return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东东咚咚东

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值