<<El algoritmo es hermoso>>——(6)——Algoritmo de retroceso (2)——N problema de la reina

contenido

prefacio

problema de n reinas

una pequeña prueba

resumen final


prefacio

Primero, familiaricémonos con el marco de retroceso que aprendimos anteriormente:

  • Camino: la elección que hacemos actualmente
  • Lista de opciones: las opciones que podemos tomar en este momento
  • Condición final : es decir, al llegar al final del árbol de decisión, no se pueden hacer más elecciones.
result=[]; 
 
def backtrack(路径,选择列表)
 
     if 满足结束条件: 
 
        result.add(路径);
 
        return 
 
    for 选择 in 选择列表 
 
        做选择
 
        backtrack(路径,选择列表)
 
        撤销选择
 

problema de n reinas

Esta pregunta es muy clásica. Creo que muchos amigos la han visto y tienen bastante miedo. Hoy seguiremos la plantilla que aprendimos anteriormente. De repente te iluminarás y tendrás una comprensión más profunda de la aplicación de esta plantilla.

Primero analiza el tema:

Es un tablero de ajedrez n * n dado, coloque n piezas de ajedrez en él y asegúrese de que la misma fila, la misma columna, la esquina superior izquierda, la esquina inferior izquierda, la esquina superior derecha y la esquina inferior derecha tienen solo una pieza de ajedrez Dibujemos y analicemos

En primer lugar, cuando caminamos desde la primera cuadrícula en la primera fila, nos encontraremos con que no podemos avanzar más cuando lleguemos a la segunda fila, entonces revoquemos y regresemos y busquemos otro camino.

No puedo hacerlo aquí de nuevo, tengo que deshacer y volver atrás. La segunda fila no se puede seleccionar, así que solo puedo deshacerlo en la primera fila y volver a seleccionarlo.

¡Funcionó! ! Este es solo un caso, y tenemos que seguir buscando otras clases también. No iré más lejos aquí. Los estudiantes interesados ​​pueden bajar y tratar de entender a través del dibujo de arriba. Debería ser un poco de reflexión. ¿No es [Path] más pequeña que las reinas que se han colocado con éxito en estas filas? , [ Lista de selección] Todos los elementos en una fila Las columnas son todas las elecciones de las reinas. (Sin embargo, existen algunas restricciones, que se analizan a continuación) [Condición final ] Cuando se supera la última fila, aquí analizamos el control de restricción:

Las filas y columnas se ven bien, analiza principalmente las líneas diagonales

Encontrarás la diagonal izquierda xy=1; diagonal derecha: x+y=5; ok, aquí terminamos el análisis, veamos el código

#include<iostream>
using namespace std;
//这里用4*4来做演示
int n = 4;
int ants;
int rec[4];
//bool check(int x, int y)
//{
//	for (int i = 0; i < n; i++)
//	{
//		if (rec[i] == y)//同一列
//		{
//			return false;
//		}
//		if (rec[i] + i == x + y)//右对角线
//		{
//			return false;
//		}
//		if (i - rec[i] == x - y)//左对角线
//		{
//			return false;
//		}
//	}
//	return true;
//}
void dfs(int row)//row当前处理的行
{
	if (row == n)//结束条件
	{
		ants++;
		return;
	}
	for (int col = 0; col < n; col++)
	{
		bool ok = true;
		for (int i = 0; i < row; i++)
		{
			//检查是否合法,与check一样
			if (rec[i] == col || i + rec[i] == row + col || rec[i] - i == col - row)
			{
				ok = false;
				break;
			}
		}
		if (ok)
		{
			rec[row] = col;//做选择
			dfs(row + 1);//进入下一行决策
			rec[row] = 0;//回溯,撤销选择
		}

	}
}
int main()
{
	dfs(0);
	cout << ants << endl;
	return 0;
}

una pequeña prueba

reina norte

resumen final

El algoritmo de retroceso es un problema transversal de varios árboles. La clave es realizar algunas operaciones en la posición de recorrido previo al pedido y recorrido posterior al pedido. El marco del algoritmo es el siguiente:

def backtrack(...):
    for 选择 in 选择列表:
        做选择
        backtrack(...)
        撤销选择

Al escribir  backtrack una función, es necesario mantener el "camino" que se ha recorrido y la "lista de opciones" que se puede hacer en este momento. Cuando se activa la "condición final", el "camino" se registra en el conjunto de resultados .

Hasta cierto punto, la fase de fuerza bruta de la programación dinámica es el algoritmo de retroceso. Es solo que algunos problemas tienen la naturaleza de subproblemas superpuestos.Puede usar la tabla dp o la optimización de memorándum para podar el árbol de recursión en gran medida, lo que se convierte en programación dinámica. Los dos problemas de hoy no tienen subproblemas superpuestos, es decir, el problema del algoritmo de retroceso, y es inevitable que la complejidad sea muy alta.

Supongo que te gusta

Origin blog.csdn.net/m0_58367586/article/details/123912329
Recomendado
Clasificación