SPOJ:M3TILE解决方案说明

时间:2013-05-05 20:02:49

标签: c++ algorithm math permutation

我一直试图解决this programming problem,但由于我无法理解,我在网上找到了一个解决方案。但我真的不明白为什么这个解决方案有效......

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

e.g。 (红线代表多米诺骨牌):

Image

当我阅读文本时,这是我第一次在纸上绘制的内容,我看到有3个可能的组合,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;
}

为什么这样做?!

3 个答案:

答案 0 :(得分:19)

T(n)成为可以使用3×n磁贴平铺2×1电路板的方式数。另外,让P(n)为使用3×n磁贴移除一个角的2×1板的平铺方式。假设n足够大(>= 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。

答案 1 :(得分:0)

答案 2 :(得分:0)

  

从左侧开始放置图块,图中显示了您最终遇到的不同类型的子问题   在每种情况下,我首先放置红色瓷砖然后黄色瓷砖和   绿色瓷砖放在最后。

     案例(a),(b),(c)

x(n)= x(n-2)+ 2 * f(n-1)

     案例(d),(e)中的

f(n)= x(n-1)+ f(n-2)。

     

我们可以用x(n)表示f(n)。

     

查看图像以获得进一步说明

Tiles Problem - Image

来源:https://www.quora.com/Can-somebody-explain-solution-to-SPOJ-com-Problem-M3TILE