Simple and easy to understand DFS (two) abstract DFS

The dfs algorithm used in topics such as mazes is easier to imagine the search process, and some problems are not so easy to imagine the search process. We call this type of problem an abstract form of dfs.

Example 1: Given n integers, it is required to select K numbers so that the sum of the selected K numbers is sum.

For problems like this, there is no obvious map for you to search; but you can still use dfs to solve this problem.

  1. For each number, there are two cases of enumerating selection or not.
  2. In the search process, we use S to record the total number of currently selected values, k to record the number of selected numbers, and deep indicates whether the number currently being enumerated is selected.
  3. In the first layer of dfs, we can enumerate whether to choose the first number, if we choose the first number, let S plus the first number and k plus 1, dfs enters the next layer; otherwise, dfs enters directly Next level.
  4. In the second layer, do the same for the second value. During the dfs process, the number of selected numbers is recorded. If k numbers have been selected, determine whether the S value is equal to sum. For each layer, we have two choices-choose and not choose. Different choices will make the search enter a different branch to continue the search

With the help of the above dfs idea, the following code can be written:

#include <iostream>
using namespace std;
int a[40];
int n, k, sum, ans;
//i表示选择第i个数,cnt记录选择的个数,s表示选取数的和
void dfs(int i, int cnt, int s) {
	if (i == n) {
		if (cnt == k && s == sum) {
			ans++;
		}
		return;
	}
	dfs(i + 1, cnt, s); //不选该数
	dfs(i + 1, cnt + 1, s + a[i]); //选择该数
}
int main() {
	cin >> n >> k >> sum;
	for (int i = 0; i < n; ++i) {
		cin >> a[i];
	}
	ans = 0;
	dfs(0, 0, 0);
	cout << ans << endl;
	return 0;
}

input:

5 3 9
1 2 3 4 5

output:

2

Example 2: N queen problem

The N queen problem is a classic problem. Place N queens on a N∗N chessboard, and place one after each row to prevent each other from attacking (the queens in the same row, the same column, and the same diagonal line will automatically attack ) The
Insert picture description here
above picture is a legal solution of 8 queens. The N queen problem refers to: how many ways to place N queens in total

This question can also use the idea of ​​dfs, that is, first determine which positions are filled in the first row, and then mark the positions that cannot be filled on the board according to the position of the first row of filling (not the same row, the same column, and the same slash), and then Fill the next line, and fill the next line according to the filling position of the previous state each time, until each line has a queen.

To mark the positions on the board that cannot be filled, you can use the following more ingenious method:

//col标记列,x1标记正斜线,x2标记反斜线
int col[10], x1[20], x2[20];
col[i] = x1[r + i] = x2[r - i + n] = true;  
//r表示填充第r行,(r, i)表示放置的位置,r + i 表示正斜线,r - i + n表示反斜线
//可以简单的推理一下,每一条正斜线的r + i都相等,反斜线的r - i都相等,为了
//防止负数,加一个n确保其为正数

Then according to the above ideas, you can write the following code:

#include <iostream>
using namespace std;
int n;
int ans;
bool col[10], x1[20], x2[20];
bool check(int r, int i) {
	return !col[i] && !x1[r + i] && !x2[r - i + n];
}
void dfs(int r) {
	if (r == n) {
		ans++;
		return;
	}
	for (int i = 0; i < n; ++i) {
		if (check(r ,i)) {
			col[i] = x1[r + i] = x2[r - i + n] = true;
			dfs(r + 1);
			col[i] = x1[r + i] = x2[r - i + n] = false;
		}
	}
}
int main() {
	scanf("%d", &n);
	dfs(0);
	cout << ans << endl;
	return 0;
}

input:

4

output:

2

input1

8

output2:

92

Understanding the problem solving of dfs in abstract form is helpful to strengthen the understanding of dfs. Understanding
the solution of n queens problem can try to solve the 2n queens problem: consider this idea, decompose it into n queens problem to solve, and then pass it Enter a parameter p for dfs, and determine whether to place the black queen or the white queen according to the value of the passed parameter p (this idea is for reference only)

Guess you like

Origin blog.csdn.net/weixin_45024585/article/details/107686635
dfs