Pregunta

I couldn't write the recurrence relation to a question like below.

Given a rectangular grid, with dimensions 4 x n, how many ways are there to completely tile the grid with 2 x 2 and 2 x 1 dominoes?

Here for 2 x 1 rectangles it is done greatly, but I couldn't figure out if rectangles are 2 x 1 and 2 x 2: http://www.acmgnyr.org/year2007/h.c

Any ideas?

For example for

4x1 : 1 way

4x2 : 11 ways

4x3 : 29 ways

Code below generates all possibilities using brute force. But I want to do it using dynamic programming.

https://gist.github.com/4519601

¿Fue útil?

Solución

I think you can solve this by using a dynamic programming algorithm.

Imagine representing the grid not as a 4 x n grid of squares, but as a 4-tuple representing the widths of each individual column. Every time you place a tile, you can try placing it somewhere such that one of its squares touches the upper-left corner of the far left side of the grid. The effect of doing this is to change the effective widths of each of the columns. For example, given this 4 x 3 grid:

. . .
. . .
. . .
. . .

We would encode it as (3, 3, 3, 3). If you were to place a 2 x 2 block in the upper corner, you'd get this:

X X .
X X .
. . .
. . .

This would be encoded as (1, 1, 3, 3), since the top two rows are now effectively much smaller.

This suggests an initial (inefficient) recursive algorithm. As your base cases, the world (0, 0, 0, 0) has just one solution (namely, doing nothing). Any world where there is no legal way to place a tile that covers the topmost square of the leftmost row has no solution. Otherwise, for all possible moves, make that move, update the internal representation of the world, and recursively add in all solutions you can find in that smaller world.

This is extremely slow (exponentially so), but can be dramatically sped up. In particular, note that the number of possible 4-tuples is (n + 1)4. This means that the maximum number of unique recursive calls is O(n4). Therefore, if you memoize your recursive calls or use dynamic programming to compute the calls backwards, you only have to make a polynomial number of calls. Memoization should be very easy to add to an existing recursive solution, and the speedup should be pretty enormous.

If you're looking for a more mathematically precise way of solving this problem, consider trying to write out a generating function for this problem and using it to derive a closed-form solution. Once you have that, it shouldn't be all that hard to evaluate it directly much more efficiently than the above solution. Since I'm not an expert in generating functions, though, I'm not actually sure how you'd do this.

Hope this helps!

Otros consejos

In 4xn, n is either even or odd. if n is even, just use 2x2 dominoes. Otherwise, use 2x2 up to n-1. Then use two 2x1 dominoes to finish the 4x1 remaining block. In answering I did not follow your link as I assume the question is sufficiently stated and the link is simply your answer to a simpler problem.

n = even

use n 2x2 dominoes

n = odd

use n-1 2x2 dominoes plus 2 2x1 domino
  • if n = 10 then 4*10=40 and (2x2)*10=40

  • if n = 11 then 4*11=44 and (2x2)*10=40 and (2x1)*2=4 for a total of 44

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top