Python 砖塔建筑之谜

Python 砖塔建筑之谜,python,Python,有人给了我一个小小的脑筋急转弯来解决 任务是使用单个整数参数生成函数。你必须计算出在给定的砖块数量下,你可以制作多少不同的塔型组合(每座塔的高度必须小于前一座塔,诸如此类)。必须有两个或两个以上的塔,一个紧挨着另一个 例如,如果给定3个区块,则只能生成1个塔楼组合,其中一个高度为2,其相邻的塔楼高度为1: | | | 2 1 给定4,您仍然只能生成一个组合,因为下一个塔必须比上一个塔短: | | | | 3 1 给定5,您可以生成2个组合: | | | | | 4 1 | | | | |

有人给了我一个小小的脑筋急转弯来解决

任务是使用单个整数参数生成函数。你必须计算出在给定的砖块数量下,你可以制作多少不同的塔型组合(每座塔的高度必须小于前一座塔,诸如此类)。必须有两个或两个以上的塔,一个紧挨着另一个

例如,如果给定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个组合),但它不适用于纸张上无法实现的更大数量。

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


我的建议是重新考虑函数,试着考虑这样一个想法,即你可以在一个不到N高的塔顶上堆叠N个块。

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

我的建议是重新考虑这个函数,试着考虑这样一个想法,即你可以在一个高度小于N的塔顶上堆叠许多块N。

给出了N个分区的生成函数,这些分区的不同部分为q(N)=乘积(1+x^k),k=1..无穷大。如果排除单个塔架的可能性,则不同的有效塔架布置的数量为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
T(0,0)=1
如果i>0,T(i,0)=0
如果i=k
然后可以观察到,在对k循环进行
j
迭代之后,
A
包含
T(j,i)
对于
i
0
n
的值。更新的过程相当谨慎,从末尾向后更新数组,这样结果只有在使用后才会更改。

给出了n个分区的生成函数,其中k=1..无穷大的分区数的不同部分为q(n)=乘积(1+x^k)。如果排除单个塔架的可能性,则不同的有效塔架布置的数量为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
T(0,0)=1
如果i>0,T(i,0)=0
如果i=k

然后可以观察到,在对k循环进行
j
迭代之后,
A
包含
T(j,i)
对于
i
0
n
的值。更新的过程有些谨慎,从末尾向后更新数组,这样结果只有在使用后才会更改。

当I\n I\n I\n I\n有效时,为什么我们不能使用I\n I\n I\n I\n请您澄清这个问题。这个问题看起来有点宽泛,此处发布的问题应提供一个答案,请在编辑较小值的postfirst检查之前完成2分钟-这将更容易在纸上检查结果。您可以随时使用
print()
查看代码中发生了什么-也许这不是您所期望的。当I\n I\n I\n I\n有效时,为什么我们不能使用I\n I\n I\n I\n I\n请您澄清这个问题。这个问题看起来有点宽泛,此处发布的问题应提供一个答案,请在编辑您的postfirst检查之前完成2分钟,以获得较小的值-这将更容易