Não consegui escrever a relação de recorrência para uma pergunta como a abaixo.
Dada uma grade retangular, com dimensões de 4 x n, quantas maneiras existem para revestir completamente a grade com dominós 2 x 2 e 2 x 1?
Aqui, para retângulos 2 x 1, é muito bem feito, mas não consegui descobrir se os retângulos são 2 x 1 e 2 x 2: http://www.acmgnyr.org/year2007/h.c
Alguma ideia?
Por exemplo, para
4x1: 1 caminho
4x2: 11 maneiras
4x3: 29 maneiras
O código abaixo gera todas as possibilidades usando força bruta. Mas eu quero fazer isso usando programação dinâmica.
https://gist.github.com/4519601
Respostas:
2 para resposta № 1Acho que você pode resolver isso usando um algoritmo de programação dinâmico.
Imagine representar a grade não como uma grade 4 x nde quadrados, mas como uma 4 tupla que representa as larguras de cada coluna individual. Cada vez que você coloca um ladrilho, você pode tentar colocá-lo em algum lugar de forma que um de seus quadrados toque o canto superior esquerdo do lado esquerdo da grade. O efeito disso é alterar a largura efetiva de cada uma das colunas. Por exemplo, dada esta grade 4 x 3:
. . .
. . .
. . .
. . .
Nós o codificaríamos como (3, 3, 3, 3). Se você colocasse um bloco de 2 x 2 no canto superior, você obteria o seguinte:
X X .
X X .
. . .
. . .
Isso seria codificado como (1, 1, 3, 3), uma vez que as duas linhas superiores agora são efetivamente muito menores.
Isso sugere uma recursiva inicial (ineficiente)algoritmo. Como seus casos básicos, o mundo (0, 0, 0, 0) tem apenas uma solução (ou seja, não fazer nada). Qualquer mundo onde não haja uma maneira legal de colocar um ladrilho que cubra o quadrado superior da linha mais à esquerda não tem solução. Caso contrário, para todos os movimentos possíveis, faça esse movimento, atualize a representação interna do mundo e adicione recursivamente em todas as soluções que você pode encontrar naquele mundo menor.
Isso é extremamente lento (exponencialmente), mas pode ser dramaticamente acelerado. Em particular, observe que o número de 4 tuplas possíveis é (n + 1)4. Isso significa que o número máximo de chamadas recursivas únicas é O (n4) Portanto, se você memorizar suas chamadas recursivas ou usar a programação dinâmica para computar as chamadas de trás para frente, você só precisa fazer um número polinomial de chamadas. A memorização deve ser muito fácil de adicionar a uma solução recursiva existente e a aceleração deve ser enorme.
Se você está procurando por um método mais matemáticomaneira precisa de resolver este problema, considere tentar escrever uma função geradora para este problema e usá-la para derivar uma solução de forma fechada. Depois de ter isso, não deve ser tão difícil avaliá-lo diretamente com muito mais eficiência do que a solução acima. Como não sou um especialista em geração de funções, não tenho certeza de como você faria isso .
Espero que isto ajude!
0 para resposta № 2
Dentro 4xn
, n
é par ou ímpar. E se n
é mesmo, é só usar 2x2
dominó. Caso contrário, use 2x2
até n-1
. Então use dois 2x1
dominó para terminar o 4x1
bloco restante. Ao responder, não segui seu link, pois presumo que a pergunta esteja suficientemente formulada e o link seja simplesmente sua resposta a um problema mais simples.
n = par
use n 2x2 dominoes
n = ímpar
use n-1 2x2 dominoes plus 2 2x1 domino
se n = 10, então 4 * 10 = 40 e (2x2) * 10 = 40
se n = 11, então 4 * 11 = 44 e (2x2) * 10 = 40 e (2x1) * 2 = 4 para um total de 44