回溯初级

Posted Ybit

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了回溯初级相关的知识,希望对你有一定的参考价值。

回溯算法

一种带有条件限制的穷举算法

1. 常用场景

在某种限制下求可行方案数最优解

2. 算法思想

在满足条件的情况下选择一个方法/路径进行运算,运算完毕后回到选择之前,换一种选择继续运算,直至无选择。

3. 模板

回溯算法往往和递归密切相关,一般模板如下:

void dfs() {
	if (terminating condition)
	for (alternative) {
		dfs();
		recover
	}
}

4. 经典例题

  • N皇后
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 8;
int dx[] = {-1, -1, -1, 0, 0, 1, 1, 1};
int dy[] = {-1, 0, 1, -1, 1, -1, 0, 1};
int ans = 0;

vector<vector<int>> board(N, vector<int>(N, 0));

void use(int x, int y) {
    int xx, yy;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < 8; j++) {
            xx = x + i * dx[j];
            yy = y + i * dy[j];
            if (xx >= 0 && xx < N && yy >= 0 && yy < N) {
                board[xx][yy] = 1;
            }
        }
    }
}
void dfs(int x, int t) {
    if (t == N) {
        ans++;
        return;
    }
    vector<vector<int>> tmp = board;
    for (int i = 0; i < N; i++) {
        if (!board[x][i]) {
            use(x, i);
            dfs(x + 1, t + 1);
        }
        board = tmp;
    }
}
int main() {
    dfs(0, 0);
    cout << ans << endl;
    return 0;
}
  • POJ1321 棋盘问题
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

const int N = 10;
int n, k, ans;
int vis[10];
char board[N][N];

void dfs(int x, int t) {
    if (t == k) {
        ans++;
        return;
    }
    if (x == n)
        return;
    for (int i = 0; i < n; i++) {
        if (vis[i] || board[x][i] != \'#\')
            continue;
        vis[i] = 1;
        dfs(x + 1, t + 1);
        vis[i] = 0;
    }
    dfs(x + 1, t);
}

int main() {
    while (scanf("%d %d",&n,&k)) {
        if (n == -1 && k == -1)
            break;
        for (int i = 0; i < n; i++)
            scanf("%s", board[i]);
        ans = 0;
        dfs(0, 0);
        printf("%d\\n", ans);
    }
    return 0;
}

以上是关于回溯初级的主要内容,如果未能解决你的问题,请参考以下文章

[AndroidStudio]_[初级]_[配置自动完成的代码片段]

[AndroidStudio]_[初级]_[配置自动完成的代码片段]

[AndroidStudio]_[初级]_[配置自动完成的代码片段]

2016-2017-1 20155215 信息安全技术 补课上测试

如何在选项卡式活动中设置片段从右到左开始

Docker初级——介绍安装和使用