Coche II

Coche II

Descripción

Hay un tablero de ajedrez con n m (n, m≤80, n m≤80), y k (k≤20) piezas deben colocarse en el tablero de modo que dos piezas no estén adyacentes. Encuentre el número total de programas legales.

Entrada
n, m, k


Número total de soluciones de salida

Entrada de muestra

3 3 2

Salida de muestra

24

Ideas: la
observación del sujeto dado el tamaño, n, m≤80, SC para usar esta escala es difícil, 280 ya sea en el tiempo o en el espacio no puede permitirse
Sin embargo, también vemos n * m≤80
poco pensamiento que podemos encontrar : 9 * 9 = 81> 80, es decir, si nym son ambos mayores o iguales que 9, la condición de n * m≤80 ya no se cumplirá. Por lo tanto, tenemos nom menor o igual que 8, ¡y 2 8 es aceptable! Entonces podemos usar la presión estatal dp.

El título y el automóvil es un poco parecido, pero solo se puede poner un automóvil en una línea, y este problema, pero solo la restricción por fila, piezas por columna, no es un automóvil adyacente, puede enumerar el estado de ubicación de cada línea, aún es factible. Para el auto II, usamos una matriz s [] para registrar los estados de ubicación tot de cada fila, s se puede preprocesar con dfs por adelantado, y c [] se usa para guardar el número de 1 en el i-ésimo estado para evitar cálculos repetidos

void dfs(ll  ans, ll  dep, ll  flag)
{
    
    
	if(dep > n) 
	{
    
    
		s[++tot]=ans;
		c[tot]=flag; 
		return;
	}
	dfs(ans, dep + 1, flag);
	dfs(ans + (1 << (dep - 1)), dep + 2, flag+1);
}

Usamos f [i] [j] [k] f [i] [j] [k]f [ i ] [ j ] [ k ] significa eliiEl estado de la fila i ess [j] s [j]s [ j ] y antes deiiColoque un total dekk en lafila ik piezas (pn pnp n reemplazakken la pregunta originalk ) El número de planes. Siga el método de enumerar el esquema de línea actual, siempre que el esquema de ubicación de la línea actual no entre en conflicto con la línea anterior. Microscópicamente hablando, significa el estado de dos líneass 1 s1s 1 ys 2 s2s 2 no es lo mismo que1 1El bit de 1 , es decir, s1 & s2 = 0, en otras palabras: s2 es el complemento de s1.

Conociendo el estado de la i-ésima fila, ¿crees que es suficiente? El problema también requiere que dos piezas no sean adyacentes. Entonces tenemos que incluir i-1. Obtenemos la recurrencia:

Límite: f [0] [1] [0] = 1; Límite: f [0] [1] [0] = 1; Límite lateral : F [ 0 ] [ . 1 ] [ 0 ]=1 ;
fi, j, k = ∑ fi - 1, p, k - cj f_ {i, j, k} = \ sum f_ {i-1, p, k-c_j}Fi , j , k=Fyo - 1 , p , k - cj
Finalmente, solo necesitamos enumerar los métodos de colocación de tot de cada fila y obtener la respuesta basada en el principio de suma.

código:

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

ll  n, m, K, c[10010], s[10010], tot, f[82][1<<9][21], ans;

void dfs(ll  ans, ll  dep, ll  flag)
{
    
    
	if(dep > n) 
	{
    
    
		s[++tot]=ans;
		c[tot]=flag; 
		return;
	}
	dfs(ans, dep + 1, flag);
	dfs(ans + (1 << (dep - 1)), dep + 2, flag+1);
}
int  main()
{
    
    
	scanf("%lld%lld%lld", &n, &m, &K);
	if(n > m)	swap(n, m);
	dfs(0, 1, 0);
	for(ll i=1; i<=tot; i++) f[1][s[i]][c[i]]=1;
	for(ll i=2; i<=m; i++)
		for(ll now=1; now<=tot; now++)
			for(ll last=1; last<=tot; last++)
				if(!(s[now] & s[last]))		
					for(ll k=0; k<=K; k++)
						if(k>=c[now])
							f[i][s[now]][k]+=f[i-1][s[last]][k-c[now]];
	for(ll i=1; i<=tot; i++) ans+=f[m][s[i]][K];
	printf("%lld", ans);
	return 0;
} 

Supongo que te gusta

Origin blog.csdn.net/bigwinner888/article/details/108115644
Recomendado
Clasificación