砖塔建筑拼图

时间:2016-12-26 03:21:33

标签: python

我得到了一个小脑筋急转弯来解决。

任务是使用单个整数参数创建一个函数。您必须弄清楚您可以使用给定数量的砖块制作多少种不同的塔架模式组合(每个前进塔架的高度必须低于之前的塔架,有点像)。必须有两个或更多的塔,一个在另一个旁边。

例如,如果您获得了3个区块,则只能生成1个塔组合,其中一个塔的高度为2,其邻居的高度为1:

|
| |
2 1

鉴于4,你只能生产一个组合,因为下一个塔必须比前一个塔短:

|
|
| |
3 1

鉴于5,你可以产生2种组合:

|
|
|
| |
4 1

|
| |
| |
3 2

我有一个可以完成所有这一切的功能,但是他们给出了200个块应该产生487067745的例子。我的功能根本就没有。我不知道我做错了什么。推动正确的方向将非常受欢迎。我的功能现在看起来像这样:

def answer(num):
    # divide the blocks so we have two towers, one with a height of n-1 and 
    # the other with a height of one
    l1 = num-1
    l2 = 1
    combinations = 0
    while True:
        if l1 > l2:
            # add 1 to the combinations along with how many combinations we 
            # can make using the blocks from tower two
            combinations += 1 + answer(l2)
        elif l1 == l2:
            # see if we can make additional towers out of the rightmost tower
            # and add that to the combinations
            combinations += answer( l2 )
        else:
            # if the first tower is smaller than or equal to the other tower 
            # then we stop trying to make combinations
            return combinations
        l1 -= 1
        l2 += 1 

虽然这种方法适用于较少数量的砖块(5个块体返回2个组合块,3个或4个块体返回1个组合块),但它不适用于纸张上无法做到的更大数量的砖块。 / p>

2 个答案:

答案 0 :(得分:3)

Wikipedia给出具有不同部分的n的分区数的生成函数,其中q(n)=乘积(1 + x ^ k),其中k = 1..nfinity。鉴于您排除了单塔的可能性,不同有效塔排列的数量为q(n)-1。

这给出了这个整齐的O(n ^ 2)时间和O(n)空间程序,用于计算塔的布置。

def towers(n):
    A = [1] + [0] * n
    for k in xrange(1, n+1):
        for i in xrange(n, k-1, -1):
            A[i] += A[i-k]
    return A[n] - 1

print towers(200)

输出是必需的:

487067745

为了理解代码,可以观察到A存储k = 1 ...无穷大的生成函数乘积(1 + x ^ k)的前n + 1个系数。每次通过k循环,我们都会向产品添加一个术语。我们可以停在n而不是无穷大,因为产品的后续条款不会影响前n + 1个系数。

考虑代码的另一种更直接的方法是将T(i, k)定义为具有i块的塔组合(包括单塔)的数量,以及任何最大高度塔是k。然后:

T(0, 0) = 1
T(i, 0) = 0 if i > 0

T(i, k) = T(i, k-1)               if i < k
        = T(i, k-1) + T(i-k, k-1) if i >= k

然后我们可以观察到,在j循环的for k次迭代后,A包含来自T(j, i)的{​​{1}}的{​​{1}}值到i。更新有点小心,从最后向后更新数组,以便结果只有在使用后才会更改。

答案 1 :(得分:1)

想象一下调用函数answer(6)。您的代码返回2,但正确的答案是3(5,1; 4,2; 3,2,1)。为什么是这样?当底部塔楼上方的街区数量大于底部塔楼的长度时,您的代码会停止,因此它会看到3,3并停止,因此从不考虑组合3,2,1。

我的建议是重新考虑这个功能,试着考虑一下你可以在一个小于N高的塔顶堆叠多个块N的想法。