Padrão de bloqueio 4 por 3
Me deparei com issoproblema.
que pede para calcular o número de maneiras que um padrão de bloqueio de um comprimento específico pode ser feito na grade 4x3 e segue as regras.pode haver alguns dos pontos que não devem ser incluídos no caminho
Um padrão válido possui as seguintes propriedades:
Um padrão pode ser representado usando a sequência de pontos que ele toca pela primeira vez (na mesma ordem em que o desenho é desenhado), um padrão que vai de (1,1) a (2,2) não é o mesmo que um padrão passando de (2,2) para (1,1).
Para cada dois pontos consecutivos A e B na representação do padrão, se o segmento de linha que liga A e B passa por alguns outros pontos, esses pontos também devem estar na sequência e vêm antes de A e B, caso contrário, o padrão será inválido. Por exemplo, uma representação de padrão que começa com (3,1) e depois (1,3) é inválida porque o segmento passa por (2,2) que não apareceu na representação de padrão antes (3,1) e a correta a representação para esse padrão é (3,1) (2,2) (1,3). Mas o padrão (2,2) (3,2) (3,1) (1,3) é válido porque (2,2) apareceu antes (3,1).
Na representação do padrão, não mencionamos o mesmo ponto mais de uma vez, mesmo que o padrão toque novamente nesse ponto através de outro segmento válido, e cada segmento no padrão deve estar indo de um ponto para outro ponto que o padrão não fez. t toque antes e poderá passar por alguns pontos que já apareceram no padrão.
O comprimento de um padrão é a soma das distâncias de Manhattan entre cada dois pontos consecutivos na representação do padrão. A distância de Manhattan entre dois pontos (X1, Y1) e (X2, Y2) é | X1 - X2 | + | Y1 - Y2 | (onde | X | significa o valor absoluto de X).
Um padrão deve tocar pelo menos dois pontos
minha abordagem foi uma força bruta, fiz um loop sobre os pontos, comece no ponto e use decremente recursivo o comprimento até atingir um comprimento zero e adicione 1 ao número de combinações.
Existe uma maneira de calculá-lo na equação matemática ou existe um algoritmo melhor para isso?
ATUALIZAR: aqui está o que eu fiz, dá algumas respostas erradas! Eu acho que o problema está emisOk
função!notAllowed
é uma máscara de bits global dos pontos não permitidos.
bool isOk(int i, int j, int di,int dj, ll visited){
int mini = (i<di)?i:di;
int minj = (j<dj)?j:dj;
if(abs(i-di) == 2 && abs(j-dj) == 2 && !getbit(visited, mini+1, minj+1) )
return false;
if(di == i && abs(j - dj) == 2 && !getbit(visited, i,minj+1) )
return false;
if(di == i && abs(j-dj) == 3 && (!getbit(visited, i,1) || !getbit(visited, i,2)) )
return false;
if(dj == j && abs(i - di) == 2 && !getbit(visited, 1,j) )
return false;
return true;
}
int f(int i, int j, ll visited, int l){
if(l > L) return 0;
short& res = dp[i][j][visited][l];
if(res != -1) return res;
res = 0;
if(l == L) return ++res;
for(int di=0 ; di<gN ; ++di){
for(int dj=0 ; dj<gM ; ++dj){
if( getbit(notAllowed, di, dj) || getbit(visited, di, dj) || !isOk(i,j, di,dj, visited) )
continue;
res += f(di, dj, setbit(visited, di, dj), l+dist(i,j , di,dj));
}
}
return res;
}