7

我一直在尝试解决这个编程问题,但由于我无法弄清楚,我在网上找到了一个解决方案。但我真的不明白为什么该解决方案也有效..

n >= 0任务是计算 3*n( ,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;
}

为什么这行得通?!

4

2 回答 2

23

让我们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)withn-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)

qed

于 2013-05-05T20:33:11.297 回答
2

分享我的图片 tut. 希望它有帮助。

于 2015-12-16T08:24:30.420 回答