用 2 x 1 多米诺骨牌填充 3xN 瓷砖的方法数(SPOJ:M3TILE)

Posted

技术标签:

【中文标题】用 2 x 1 多米诺骨牌填充 3xN 瓷砖的方法数(SPOJ:M3TILE)【英文标题】:Number of ways to fill 3xN tiles with 2 x 1 dominoes (SPOJ: M3TILE) 【发布时间】:2013-05-05 20:02:49 【问题描述】:

我一直在尝试解决this programming problem,但是由于我想不通,所以我在网上找到了解决方案。但我也无法真正理解为什么该解决方案也有效..

任务是计算一个 3*n(n >= 0,n 是唯一的输入)矩形有多少种方式可以完全用 2*1 多米诺骨牌填充。

例如(红线代表多米诺骨牌):

这是我在阅读课文时第一次在纸上画的,我看到 3*2 矩形可以有三种可能的组合,如果 n 是奇数,则解为 0,因为那么是没有办法填满整个矩形的(一块永远不会被多米诺骨牌覆盖)。

所以我认为解决方案只是3^n,如果 n 是偶数,0,如果 n 是奇数。原来,我错了。

我在这里找到了一个比较简单的解决方案:

#include <iostream>

using namespace std;

int main()

    int arr[31];

    arr[0]=1;
    arr[1]=0;
    arr[2]=3;
    arr[3]=0;

    for(int i = 4; i < 31; i++) 
        arr[i] = arr[i-2] * 4 - arr[i-4]; //this is the only line i don't get
    

    int n;

    while(1) 
        cin >> n;

        if(n == -1) 
            break;
        

        cout << arr[n] << endl;
    

    return 0;

为什么会这样?!

【问题讨论】:

【参考方案1】:

T(n) 是可以用2×1 拼贴3×n 板的方式数。此外,设P(n) 是用2×1 瓷砖移除一个角的3×n 板的平铺方式数。假设 n 足够大 (&gt;= 4)。

然后考虑如何从左侧(或右侧,没关系)开始平铺。

您可以通过垂直或水平两种方式放置覆盖左上角的图块。如果垂直放置,覆盖左下角的瓷砖必须水平放置,给出配置

|
==

剩下P(n-1) 方法来平铺剩余部分。如果您水平放置它,您可以水平或垂直放置覆盖左下角的瓷砖。如果竖着放,和之前的情况一样,只是反射,如果横放,就必须在它们之间横放一个瓦片,

==
==
==

给你留下一个3×(n-2) 板来平铺。因此

T(n) = T(n-2) + 2*P(n-1)              (1)

现在,考虑到3×(n-1) 板的一个角被移除(已经覆盖)(假设左上角),您可以在其下方垂直放置一块瓷砖,从而得到

=
|

给你留下一个 3×(n-2) 板来平铺,或者你可以在它下面水平放置两个瓷砖,给

=
==
==

然后你别无选择,只能在顶部水平放置另一个瓷砖,留下你

===
==
==

3×(n-3) 板减去一个角,

P(n-1) = T(n-2) + P(n-3)

加起来,

T(n) = T(n-2) + 2*(T(n-2) + P(n-3))
     = 3*T(n-2) + 2*P(n-3)                            (2)

但是,使用(1)n-2 代替n,我们看到了

T(n-2) = T(n-4) + 2*P(n-3)

2*P(n-3) = T(n-2) - T(n-4)

将其插入(2) 会产生重复

T(n) = 4*T(n-2) - T(n-4)

q.e.d.

【讨论】:

@Daniel 你能解释一下 n = 0 对应的基本情况吗? @ATulSingh 对于 n = 0,我们有一个完全没有单元的板。只有一种方法可以平铺:在上面不放瓷砖[3×0 板有 3·0 = 0 个单元格,所以你需要 0/(2·1) = 0/2 = 0 个瓷砖]。【参考方案2】:

Sharing my image tut.Hope it helps .

【讨论】:

请从链接中添加一些内容。 @Robert 你什么意思? 如果将来链接断开,那么这个答案就变得多余了。

以上是关于用 2 x 1 多米诺骨牌填充 3xN 瓷砖的方法数(SPOJ:M3TILE)的主要内容,如果未能解决你的问题,请参考以下文章

在 scala 中键入安全的多米诺骨牌

数据结构与算法之深入解析“多米诺和托米诺平铺”的求解思路与算法示例

51Nod 1031 骨牌覆盖 | Fibonacci

AOJ 589.多米诺

递归方法-库存填充

51nod1031(简单斐波拉契数列)