8223. Tiling a Grid With Dominoes

Description

We wish to tile a grid 4 units high and N units long with rectangles (dominoes) 2 units by one unit (in either orientation). For example, the figure shows the five different ways that a grid 4 units high and 2 units wide may be tiled.

 

Write a program that takes as input the width, W, of the grid and outputs the number of different ways to tile a 4-by-W <tex2html_verbatim_mark>grid.

Input

The first line of input contains a single integer N(1<=N<=1000) which is the number of datasets that follow.

Each dataset contains a single decimal integer, the width, W, of the grid for this problem instance.

Output
For each problem instance, there is one line of output: The problem instance number as a decimal integer (start counting at one), a single space and the number of tilings of a 4-by- W grid. The values of  W will be chosen so the count will fit in a 32-bit integer.
Sample Input
 Copy sample input to clipboard
3 

2 

3 

7

Sample Output
1 5 

2 11 

3 781


dp[i]表示宽度为i的排列种数。

我们可以这样分解dp[i]

i列依次分解为2部分,依次分解为 (i-1)+1列 (i-2)+2列 …… 1+(i-1)列

那么dp[i] = dp[i-1]*dp[1] + dp[i-2]*dp[2] + ……+dp[1][i-1] -R

R是重复的个数,事实上我们不必算出R,只要在计算dp[i-j]*dp[j]的时候去除掉与前面相同情况的个数即可。

首先,dp[0] = dp[1] = 1, dp[2] = 5.

少一列,最后一列的2个只能都是竖的对不对,所以是左边部分是dp[i-1],右边部分是dp[1]。少两列,左边部分是dp[i-2],右边部分是dp[2]-1=4

如图,为了防止跟少1列的情况重复,所以倒数第二列不能2个竖的,剩下的几种可能画个图就明白。

8223. Tiling a Grid With Dominoes 

少j列,依然用这种思路,为了保证不跟前面的情况重复,我们倒数第j列必然不能是2个竖的。所以剩下4种可能,画图填充,就知道有几种可能。

例如,少3列的时候,只有2种情况,所以dp[i-3]*2

8223. Tiling a Grid With Dominoes

画着画着就知道:≥ 3

少奇数列的时候(也就是j为奇数的时候),总数为dp[i-j]*2

少偶数列的时候(也就是j为偶数的时候),总数为dp[i-j]*3

 

所以状态转移方程就来啦:

dp[i]=dp[i-1]+4*dp[i-2]+2*(dp[i-3]+dp[i-5]...)+3*(dp[i-4]+dp[i-6]...)

 

#include <cstdlib>

#include <iostream>

using namespace std;

#define Max 1002



int dp[Max];



void init()

{

    dp[0] = 1;

    dp[1] = 1;

    dp[2] = 5;

    

    for (int i = 3; i <= Max; i++)

    {

        dp[i] = dp[i-1] + 4*dp[i-2];

        

        for(int j = 3; j <= i; j++)

            if(j%2)

                dp[i] += 2*dp[i-j];

            else

                dp[i] += 3*dp[i-j];

    }

}



int main()

{    

    init();

    

    int m, n, cases = 1;

    

    cin >> m;

    

    while (m--)

    {

       cin >> n;

       

       cout << cases++ <<" "<< dp[n] <<endl;

    }

}
View Code

 

你可能感兴趣的:(grid)