coche
Descripción
Coloque n coches en el tablero de ajedrez cuadrado n * n (n≤20) (puede atacar la fila y la columna), algunos cuadrados no se pueden colocar, encuentre el número total de planos que no pueden atacarse entre sí.
Entrada
El tamaño del tablero de ajedrez en la primera línea n
El número de obstáculos en la
segunda línea m La tercera línea am + 3 son m obstáculos
Salida
total
Entrada de muestra
4
2
1 1
2 2
Salida de muestra
14
Pensamiento:
para ai a_iunyoRepresenta el estado de la i-ésima fila, 1 es barrera, 0 es sin barreras. ¿Cómo se transfiere?
a[i]+=1 << (y - 1);
注意:它是在边数人边输出的,x,y表示障碍的位置。
Luego configuramos f [i] para representar el número total de opciones con la mayoría de i autos seleccionados. ¿Se basa en el principio de la suma, sumamos todos los estados antes del estado actual a un total, es ese el valor máximo de f [i]?
for(ll i=1,c,j ; i<(1 << n) ; i++)
{
for(c=0,j=i ; j ; j-=(j & -j),c++);
for(j=i&~a[c]; j; j-=(j&-j)) f[i]+=f[i^(j&-j)];
}
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#define ll long long
#define fre(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout);
using namespace std;
const ll MAX=2147483647;
const ll N=1 << 20;
ll n, m, x, y, a[N], f[N]={
1};
int main()
{
scanf("%lld%lld",&n, &m);
for(ll i=1; i<=m; i++) scanf("%lld%lld", &x, &y), a[x]+=1 << (y - 1);
for(ll i=1, c, j; i<(1 << n) ; i++)
{
for(c=0, j=i ; j ; j-=(j & -j),c++);
for(j=i&~a[c]; j; j-=(j&-j)) f[i]+=f[i^(j&-j)];
}
printf("%lld",f[(1 << n) - 1]);
return 0;
}