DFS simple y fácil de entender (dos) DFS abstracto

El algoritmo dfs utilizado en temas como laberintos es más fácil de imaginar el proceso de búsqueda, y algunos problemas no son tan fáciles de imaginar en el proceso de búsqueda. Llamamos a este tipo de problema una forma abstracta de dfs.

Ejemplo 1: Dados n números enteros, es necesario seleccionar K números para que la suma de los K números seleccionados sea la suma.

Para problemas como este, no hay un mapa obvio para buscar, pero aún puede usar dfs para resolver este problema.

  1. Para cada número, hay dos casos de enumeración de selección o no.
  2. En el proceso de búsqueda, usamos S para registrar el número total de valores seleccionados actualmente, k para registrar el número de números seleccionados y deep indica si el número que se está enumerando actualmente está seleccionado.
  3. En la primera capa de dfs, podemos enumerar si elegir el primer número. Si se selecciona el primer número, agregue S al primer número yk más 1, dfs ingresa a la siguiente capa; de lo contrario, dfs ingresa directamente al siguiente nivel.
  4. En la segunda capa, haga el mismo proceso para el segundo valor. Durante el proceso dfs, se registra el número de números seleccionados. Si se han seleccionado k números, determine si el valor S es igual a la suma. Para cada capa, tenemos dos opciones: elegir y no elegir. Diferentes opciones harán que la búsqueda ingrese a una rama diferente para continuar la búsqueda.

Con la ayuda de la idea dfs anterior, se puede escribir el siguiente código:

#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;
}

aporte:

5 3 9
1 2 3 4 5

producción:

2

Ejemplo 2: problema de N reina

El problema de las N reinas es un problema clásico. Coloca N reinas en un tablero de ajedrez de N, N y coloca una después de cada fila para evitar que la otra se ataque (las reinas en la misma fila, la misma columna y la misma línea diagonal aparecerán automáticamente ataque) La
Inserte la descripción de la imagen aquí
imagen de arriba es una solución legal de 8 reinas. El problema de N reinas se refiere a: cuántas formas de colocar N reinas en total

Esta pregunta también puede usar la idea de dfs, es decir, primero determine qué posiciones se llenan en la primera fila y luego marque las posiciones en el tablero que no se pueden llenar de acuerdo con la posición de la primera fila (no es lo mismo fila, la misma columna y la misma línea diagonal) Llene la siguiente línea y complete la siguiente línea de acuerdo con la posición de llenado del estado anterior cada vez, hasta que cada línea tenga una reina.

Para marcar las posiciones en el tablero que no se pueden llenar, puede utilizar el siguiente método más ingenioso:

//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确保其为正数

Luego, de acuerdo con las ideas anteriores, puede escribir el siguiente código:

#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;
}

aporte:

4

producción:

2

entrada1

8

salida2:

92

Comprender la resolución de problemas de dfs en forma abstracta es útil para fortalecer la comprensión de dfs. Comprender
la solución del problema de n reinas puede intentar resolver el problema de 2n reinas: considere esta idea, descompóngala en un problema de n reinas para resolver y luego pasar Ingrese un parámetro p para dfs y determine si colocar la reina negra o la reina blanca de acuerdo con el valor del parámetro p pasado (esta idea es solo para referencia)

Supongo que te gusta

Origin blog.csdn.net/weixin_45024585/article/details/107686635
Recomendado
Clasificación