hdu 1992 Tiling a Grid With Dominoes

Tiling a Grid With Dominoes

Time Limit: 1000/500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 410    Accepted Submission(s): 321


Problem 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 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
  
  
3 2 3 7
 

Sample Output
  
  
1 5 2 11 3 781
 

Source
 

Recommend
linle

总结了三种方法

1.用dp[n][m]表示排到第n列时,且第n列的状态为m(用四位2进制数表示,0表示未覆盖,1表示覆盖)时的方法数。其中m只可能取值1001=9,1100=12,0011=3,0110=6,0000=0,1111=15(思考其他的情况为什么不成立)

初始化:dp[1][0]=dp[1][3]=dp[1][6]=dp[1][12]=dp[1][15]=1;

状态转移:

                 dp[t][15]=dp[t-1][15]+dp[t-1][12]+dp[t-1][3]+dp[t-1][6]+dp[t-1][0];
          dp[t][
9=dp[t-1][6];
          dp[t][
12]=dp[t-1][15]+dp[t-1][3];
          dp[t][
3=dp[t-1][15]+dp[t-1][12];
          dp[t][
6=dp[t-1][15]+dp[t-1][9];
          dp[t][
0=dp[t-1][15];

实现的时候把t从2到1000列举就搞定了;

2.

方法二的本质和一相同,不过实现的时候将行变成列,列变成行,用1表示影响下一行,0表示不影响下一行,再用dfs(该函数计算的是下一行可能情况的值)一一列举所有的情况,即考虑了从0000~1111所有的情况。

dp[i][s]表示i行第i行状态为s的值,那么dp[n][0]就表示所求的了

关键代码:

void dfs(int s1,int s2,int p,int n)//s1为当前行状态。s2为构造的下一行状态。p为处理到第几列,n为行数。
{
    if(p>3)//一行处理完了。
    {
        dp[n+1][s2]+=dp[n][s1];
        return;
    }
    if(s1&(1<<p))
        dfs(s1,s2,p+1,n);//已被铺上砖,换到下一列
    else
    {
        dfs(s1,s2|(1<<p),p+1,n);//竖着放
        if(p<=2&&!(s1&(1<<(p+1))))//横着放
            dfs(s1,s2,p+2,n);
    }		
}
注意初始化dp[0][0]=1,其他全为0;

3.

此方法就是直接找规律了

状态转移方程:

dp[i]=dp[i-1]+4*dp[i-2]+2*(dp[i-3]+dp[i-5]+dp[i-7].+dp[i-奇数]..)+3*(dp[i-4]+dp[i-6]..-dp[i-偶数]..);

解释:将此整体分为两部分列1~kk+1~i列,即sk=(不可竖向分割的有k列的整体的)*dp[i-(i-k)],然后对sk从k=1积分到k=i-1


 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值