Consider a polyomino . We want to divide into several (may be one) smaller polyominoes. The division is called a Fillomino solution if no two polyominoes of equal size share a side. (They may touch at a point.) In other words, the division is a valid solution of a Fillomino puzzle.
Determine the number of distinct Fillomino solutions of the rectangle.
This section requires Javascript.
You are seeing this because something didn't load right. We suggest you, (a) try
refreshing the page, (b) enabling javascript if it is disabled on your browser and,
finally, (c)
loading the
non-javascript version of this page
. We're sorry about the hassle.
While the previous two problems are relatively simple, this one is very difficult compared to them. No more brute force; there are 1 0 0 cells, and each cell can hold a number as high as 1 0 0 , so testing 1 0 0 1 0 0 possibilities is awful.
The trick is that the rectangle has width 1 . Thus, all the polyominoes generated will also be rectangles of width 1 . This allows a very nice solution with dynamic programming.
The first idea would most likely be "generalize the problem, to 1 × n , and make a recurrence by considering the last polyomino"; this is similar to a common problem:
The attempt might be this: with the original 1 × n rectangle R , remove a 1 × k polyomino P to leave a 1 × ( n − k ) rectangle R ′ . Find the number of ways to complete R ′ , and add up for all possible choices of k . However, the problem is that the last polyomino of R ′ cannot be 1 × k as well, since it would be adjacent to P .
The fix is simple: we consider both n and the size of the last polyomino. Let a n , k be the number of Fillomino solutions on 1 × n , where the last polyomino (the rightmost) is 1 × k . For example, a 2 , 1 = 0 (it's impossible to fill a 1 × 2 rectangle having a 1 × 1 polyomino, since the rest is again a 1 × 1 polyomino, but then both have size 1 and are adjacent), but a 2 , 2 = 1 (just fill the whole thing with a 2-mino).
Thus, we have the simple recurrence relation:
a n , k = ⎩ ⎪ ⎨ ⎪ ⎧ 1 0 ( a n − k , 1 + a n − k , 2 + … + a n − k , n − k ) − a n − k , k if n = k if n < k if n > k
If the last polyomino is 1 × n , then the whole rectangle is not divided at all: there's one such way. If the last polyomino is 1 × k with k > n , it's clearly impossible, since the rectangle won't fit. Otherwise, the number of ways is simply the number of ways to fill 1 × ( n − k ) , with anything except 1 × k as the last polyomino.
This gives an O ( n 3 ) solution (two-dimensional states contributes O ( n 2 ) , and computing the sum is O ( n ) ). This still works, but there's a simple speed up: a n − k , 1 + a n − k , 2 + … + a n − k , n − k is constant, so we can actually simply store it instead of computing it over and over. This makes all computations O ( 1 ) , thus the running time is O ( n 2 ) , easily done even with slow languages (read: Python).
Finally, just program it:
In the above, we didn't actually compute a n , k = 0 for n < k ; instead, we simply observe if n − k < k , and use a different formula (
a[n][k] = s[n-k]
compared toa[n][k] = s[n-k] - a[n-k][k]
, corresponding to setting a n − k , k = 0 ) if that's the case.The printed answer is 9 3 1 3 2 9 6 4 7 5 8 3 2 7 2 5 3 2 8 1 5 2 2 6 .