Puzzle “如何开始”;“无裂纹墙”;问题

Puzzle “如何开始”;“无裂纹墙”;问题,puzzle,Puzzle,以下是问题陈述: 考虑用2x1和3x1砖(水平×垂直尺寸)砌墙的问题,这样,为了获得额外的强度,水平相邻砖之间的间隙不会在连续层中排列,即不会形成“连续裂缝” 形成无裂纹9x3墙有八种方法,写W(9,3)=8 计算W(32,10)。 上面的链接给出了一些解决方案,但我无法理解它们背后的逻辑。我正在尝试用Perl编写此代码,目前为止已经完成了: input : W(x,y) find all possible i's and j's such that x == 3(i) + 2(j); for

以下是问题陈述:

考虑用2x1和3x1砖(水平×垂直尺寸)砌墙的问题,这样,为了获得额外的强度,水平相邻砖之间的间隙不会在连续层中排列,即不会形成“连续裂缝”

形成无裂纹9x3墙有八种方法,写W(9,3)=8

计算W(32,10)。<把它推广到W(x,y)>

上面的链接给出了一些解决方案,但我无法理解它们背后的逻辑。我正在尝试用Perl编写此代码,目前为止已经完成了:

input : W(x,y)
find all possible i's and j's such that x == 3(i) + 2(j);
for each pair (i,j) ,
find n = (i+j)C(j)            # C:combinations
将所有这些n相加,应给出所有可能组合的计数。但我不知道如何找到一行的实际组合以及如何进一步进行。

基于W(9,3)=8的说法,我推断“连续裂缝”是指任何高度为两个或两个以上的连续垂直裂缝。在解决所提出的二维问题之前,我想讨论一个类似的一维问题及其解决方案。我希望这将使人们更清楚地认识到二维问题是如何被认为是一维的,并最终得到解决的

假设你想计算长度为40的列表的数量,它们的符号来自一个相当小的集合,比如说,五个符号{a,b,c,d,e}。当然有5^40个这样的列表。如果我们添加一个额外的约束,即任何字母都不能在一行中出现两次,那么数学解决方案仍然很简单:有5*4^39个没有重复字符的列表。然而,如果我们想取缔辅音组合,如bc、cb、bd等,那么事情就更难了。当然,我们想计算选择第一个字符、第二个字符等的方法的数量,然后乘以,但是选择第二个字符的方法的数量取决于第一个字符的选择,依此类推。这个新问题很难说明正确的技术。(虽然还不足以让它完全抵制数学方法!)


为了解决长度为40的列表没有辅音组合的问题(我们称之为f(40)),我们可以想象使用递归。你能用f(39)来计算f(40)吗?不,因为有些长度为39的列表以辅音结尾,有些以元音结尾,我们不知道每种类型有多少。因此,对于每一个长度n,我在网上找到了这段python代码,它可以快速正确地工作。我不明白这一切是如何运作的。我可以把我的C++拿到最后一步(计算解决方案总数),不能使它正确工作。< /P>
def brickwall(w,h):
    # generate single brick layer of width w (by recursion)
    def gen_layers(w):
        if w in (0,1,2,3):
            return {0:[], 1:[], 2:[[2]], 3:[[3]]}[w]
        return [(layer + [2]) for layer in gen_layers(w-2)] + \
               [(layer + [3]) for layer in gen_layers(w-3)]
    # precompute info about whether pairs of layers are compatible
    def gen_conflict_mat(layers, nlayers, w):
        # precompute internal brick positions for easy comparison
        def get_internal_positions(layer, w):
            acc = 0; intpos = set()
            for brick in layer:
                acc += brick; intpos.add(acc)
            intpos.remove(w)
            return intpos
        intpos = [get_internal_positions(layer, w) for layer in layers]        
        mat = []
        for i in range(nlayers):
            mat.append([j for j in range(nlayers) \
                              if intpos[i].isdisjoint(intpos[j])])
        return mat
    layers = gen_layers(w)
    nlayers = len(layers)
    mat = gen_conflict_mat(layers, nlayers, w)
    # dynamic programming to recursively compute wall counts
    nwalls = nlayers*[1]
    for i in range(1,h):
        nwalls = [sum(nwalls[k] for k in mat[j]) for j in range(nlayers)]
    return sum(nwalls)

print(brickwall(9,3))   #8
print(brickwall(9,4))   #10
print(brickwall(18,5))  #7958
print(brickwall(32,10)) #806844323190414