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