In how many ways can you
tile a 3 * n rectangle with 2 * 1
dominoes? Here is a sample tiling of a 3 * 12 rectangle.
Input. Consists of several test cases followed by a line containing
-1. Each test case is a line containing an integer n (0 ≤ n ≤
30).
Output. For each test case print
one integer giving the number of possible tilings.
Sample
input |
Sample
output |
2 8 12 -1 |
3 153 2131 |
dynamic
programming - combinatorics
Denote by Un the total number of tilings
of a 3 * n rectangle with horizontal
and vertical dominoes. Let Vn
denote the total number of tilings of a 3 * n
rectangle without a lower left corner with (3n – 1) / 2 dominoes.
We get the following
recurrence relations:
Un = 2Vn-1
+ Un-2
Vn = Un-1
+ Vn-2
Consider the cases for n = 1 and n = 2.
The recurrence relations
can be used not only to calculate the values of functions forward, but also
backward. By problem statement 0 ≤ n
≤ 30, so we need also the values U0 and V0. From
derived relation we obtain
or ,
Example
The values of Un and Vn for small n we
give in the table below:
In arrays u and v we shall
compute the values of Un and
Vn.
int u[31], v[31];
Compute the values of Un and Vn (n = 0, 1,
…, 30) according to the above recurrence formulas.
u[0] = v[1] = 1;
u[1] = v[0] = 0;
for(n = 2; n <= 30; n++)
{
u[n] = 2 * v[n-1] + u[n-2];
v[n] = u[n-1] + v[n-2];
}
For each input number n print u[n].
while(scanf("%d",&n),n
>= 0)
printf("%d\n",u[n]);
Java
realization
import java.util.*;
public class Main
{
public static int MAX = 31;
static int u[] = new int[MAX];
static int v[] = new int[MAX];
public static void main(String[] args)
{
Scanner con = new Scanner(System.in);
u[0] = v[1] = 1;
u[1] = v[0] = 0;
for(int n = 2; n < MAX; n++)
{
u[n] = 2 *
v[n-1] + u[n-2];
v[n] = u[n-1] + v[n-2];
}
int n = con.nextInt();
while(n >=
0)
{
System.out.println(u[n]);
n = con.nextInt();
}
}
}