Algorithm 乐高积木-动态规划
我试图解决以下DP问题: 您有4种类型的乐高积木,大小为1*1*1、1*1*2、1*1 *3和1*1*4。假设每种类型有无限多个块 你想用这些砖砌一堵高H宽M的墙。 墙上不应该有洞。你建造的墙应该是 一个固体结构。坚固的结构意味着它不应该 可沿任何垂直线分离墙壁,无需切割 用于建造墙壁的任何乐高积木。只能放置块 水平的。这堵墙可以用多少种方法建造 下面是我如何尝试的: 用bcd表示1*1*1、1*1*2、1*1*3和1*1*4块 . 有效模式以粗体表示。无效的图案可以被垂直线打断 H=1&W=3#有效模式=1Algorithm 乐高积木-动态规划,algorithm,dynamic-programming,Algorithm,Dynamic Programming,我试图解决以下DP问题: 您有4种类型的乐高积木,大小为1*1*1、1*1*2、1*1 *3和1*1*4。假设每种类型有无限多个块 你想用这些砖砌一堵高H宽M的墙。 墙上不应该有洞。你建造的墙应该是 一个固体结构。坚固的结构意味着它不应该 可沿任何垂直线分离墙壁,无需切割 用于建造墙壁的任何乐高积木。只能放置块 水平的。这堵墙可以用多少种方法建造 下面是我如何尝试的: 用bcd表示1*1*1、1*1*2、1*1*3和1*1*4块 . 有效模式以粗体表示。无效的图案可以被垂直线打断 H=1&W=3
aa ab bac
H=2&W=3#有效模式=9
我试图找到重复模式,通过高度或宽度来扩展它,也就是说,找到H=3&W=3或H=2&W=4的值 有关于如何通过身高或体重来计算增长的信息吗?
另一方面,墙始终是H*W*1。
不难找到许多1xW条纹(设为N(1,W))。 然后,您可以找到许多HxW墙(包括非实心墙)——它是(H,W)=N(1,W)^H 任何非实体墙都由左H*L墙和右H*(W-L)墙组成。似乎实心墙的数量是有限的
S(H,W)=A(H,W)-和(S(H,L)*A(H,W-L))[L=1..W-1]
S(H,L)*A(H,W-L)是在L垂直位置最左侧断裂的非实心墙的数量。第一个因素是实心墙的数量-以消除重复变体的计数。首先,让我们看看如果我们忽略保持连接的需要,我们可以建造多少M*N墙: 我们可以分别处理每一行,然后将计数相乘,因为它们是独立的 只有一种方法可以平铺
0*1
或1*1
墙,平铺n*1
的方法数是平铺{n-1}*1
的方法数的总和。…{n-4}*1
大小的墙,原因是可以通过移除n*1
墙的最后一块来获得这些墙
这就产生了一个tetranacci序列。
所有W*H
墙的数量为a(W,H)=T(W)^H
现在,来计算实体墙的数量。MBo的答案已经包含了一个基本前提:
在墙未连接的最左侧位置上的分支。A
ll W*H墙的数量是S
olid X*H墙的数量乘以A
ll{W-X}*H
墙的数量,求出X
所有可能值的总和,加上S
olid W*H墙的数量:
A(W,H) = sum{X=1..{W-1}}(S(X,H)*A(W-X,H)) + S(W,H)
作为最后一步,我们分离出S(M,H)
项,这是我们要计算的值,并重复前面的公式:
S(W,H) = A(W,H) - sum_x( S(X,H)*A(W-X,H) ) //implicitly, S(1,H)=1
A(W,H) = T(W)^H
T(X) = X > 0: T(X-1)+T(X-2)+T(X-3)+T(X-4)
X = 0: 1
X < 0: 0
S(W,H)=A(W,H)-sum_x(S(x,H)*A(W-x,H))//隐式地,S(1,H)=1
A(W,H)=T(W)^H
T(X)=X>0:T(X-1)+T(X-2)+T(X-3)+T(X-4)
X=0:1
X<0:0
(证明MBo公式正确)
这也提供了一个计算
S
的O(W^2)
算法(假设正确的记忆和恒定时间算术运算)说明:墙是M*H*1
块,还是M*H*inf
块?我假设前者(因此模式的计数是有限的),但是我看不出模式符号是如何工作的。1x3唯一有效的模式是c
,而不是b
。我能想到的最好的模式是一个带有O(4^H)
状态的马尔可夫链。这听起来更像是托盘装载问题,它是NP完全问题。我认为我们不会在多项式时间内找到精确解。@JanDvorak:谢谢你指出。这是个大错误。让我编辑我的Q@SauceMaster这种情况更容易,因为您提前知道托盘尺寸,并且所有托盘都是矩形的,并且是相同尺寸的倍数(并且不能旋转)。更困难的是,你需要让墙物理连接起来。我也这么想,但公式需要证明。你的陈述不应该是“任何非实体墙都由左侧实心H*L墙和右侧H*(W-L)墙组成”@Percy123在这一点上的文字-可能是,但不应该是。稍后我会介绍最左边休息的概念。好的,明白了。。但早些时候引入这个概念只会让它更清楚:)+1是详细的答案。然而,一个小的修正,T(0)=1。否则,对于所有X,T(X)将为0。如果我错了,请纠正我。平铺n*1
的方法数应该是平铺(n-1)*1…(n-4)*1
的方法总数,而不是(n-1)*n…(n-4)*1
,不是吗?你能告诉我如何在O(W^2)
中实现算法吗?有没有什么技巧可以在恒定时间内计算和(S(x,H)*A(W-x,H))?我想你必须填充所有的S块,它需要O(W*H)
。对所有X求和的简单实现是O(W)
,这使得算法O(W^3)
@MinhPham可以计算O(W)
每个项的总和<代码>A和S
都被记录。不过,我假设的是常数时间数学,bignums会根据你的乘法速度将其移到O(W^3.5)
。注意,在这个递归公式中,H
是常数。@JanDvorak:明白了。事实上,这个问题要求我们给出模数100000007的结果,这样就不需要bignums了。H是常数这一事实是关键。