【问题标题】:Lego Blocks - Dynamic Programming乐高积木 - 动态规划
【发布时间】:2013-03-03 17:27:07
【问题描述】:

我正在尝试解决以下 DP 问题:

您有 4 种类型的乐高积木,尺寸分别为 1 * 1 * 1、1 * 1 * 2、1 * 1 * 3 和 1 * 1 * 4。假设您有无限数量的每种类型的块。

你想用这些块做一堵高 H 宽 M 的墙。 墙上不应该有任何洞。你建造的墙应该是 一个坚固的结构。坚固的结构意味着它不应该 可以沿任何垂直线分隔墙壁而无需切割 任何用于建造墙壁的乐高积木。方块只能放置 水平。墙可以用多少种方式建造?

这是我尝试的方式: 用 a b c d 表示 1 * 1 * 1、1 * 1 * 2、1 * 1 * 3 和 1 * 1 * 4 块 .有效模式以粗体表示。无效的模式是可以被垂直线打破的。

H=1 & W=3 #valid pattern=1
aa ab ba c

H=2 & W=3 #有效模式=9

我正在尝试查找重复模式以将其扩展高度或宽度。即找到 H=3 & W=3 或 H=2&W=4 的值。

关于如何通过身高或体重来计算增长的任何意见?
附:墙总是 H*W*1。

【问题讨论】:

  • 澄清:墙是M*H*1 块,还是M*H*inf 块?我假设前者(这样模式的数量是有限的),但是我看不出你的模式符号是如何工作的。 1x3 的唯一有效模式是 c,而不是 b
  • 我能想到的最好的是带有O(4^H) 状态的马尔可夫链。这不好(或者是吗?)。
  • 这听起来更像是托盘装载问题,是NP-Complete。我认为我们不会在多项式时间内找到精确的解决方案。
  • @JanDvorak:感谢您的指出。那是个大错误。让我编辑我的 Q
  • @SauceMaster 这种情况更容易,因为您事先知道托盘尺寸,并且所有托盘都是矩形和相同尺寸的倍数(并且不能旋转)。这也更加困难,因为您需要使墙壁物理连接。

标签: algorithm dynamic-programming


【解决方案1】:

不难找到多个 1xW 的条纹(假设为 N(1,W))。 然后你可以找到一些所有(包括非实心)HxW 墙 - 它是 A(H,W) = N(1,W)^H 任何非实体墙都由左 H*L 墙和右 H*(W-L) 墙组成。似乎实体墙的数量是

S(H,W) = A(H,W) - Sum(S(H, L) * A(H, W-L)) [L=1..W-1]

S(H, L) * A(H, W-L) 是在 L 垂直位置最左边的非实心墙的数量。第一个因素是实体墙的数量 - 消除重复变体的计数。

【讨论】:

  • 我的想法是一样的,但公式需要证明。
  • 您的陈述不应该是“任何非实心墙由左侧实心 H*L 墙和右侧 H*(W-L) 墙组成”
  • @Percy123 在那个文本点 - 它可能是,但不应该。我稍后介绍最左中断的概念。
  • 好的,明白了.. 但是更早地介绍这个概念只会让它更清晰:)
【解决方案2】:

首先,让我们看看如果我们忽略保持连接的需要,我们可以建造多少 M*N 墙:

我们可以分别对待每一行,然后将计数相乘,因为它们是独立的。

平铺0*11*1 墙只有一种方法,平铺n*1 的方法数是平铺{n-1}*1...@987654326 的方法总数@大小的墙,原因是这些墙可以通过移除n*1墙的最后一个瓷砖来获得。

这产生了一个四边形序列,OEIS A000078。 所有W*H墙的数量是a(w,h)=T(w)^h

现在,数实墙的数量。 MBo 的回答已经包含了基本前提:

最左边没有连接墙的地方的分支。 All W*H 墙的数量是Solid X*H 墙的数量乘以All {W-X}*H 墙的数量,将X 的所有可能值加起来Solid W*H 墙:

A(W,H) = sum{X=1..{W-1}}(S(X,H)*A(W-X,H)) + S(W,H)

作为最后一步,我们将S(M,H) term 分开,这是我们要计算的值,并重复前面的公式:

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

(证明 MBo 的公式正确)。

这还提供了一个 O(W^2) 算法来计算 S(假设正确的记忆和恒定时间算术运算)

【讨论】:

  • +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)中的算法吗?在恒定时间内计算sum_x( S(X,H)*A(W-X),H) ) 有什么技巧吗?我想你必须填写所有需要O(W*H) 的 S 块。对所有 X 求和的简单实现是 O(W),这使得算法为 O(W^3)
  • @MinhPham 您计算 O(W) 每个 O(W) 术语的总和。 AS 都被记忆了。不过,我假设的是常数时间数学 - bignums 将其移近O(W^3.5),具体取决于您可以乘多快。请注意,H 在此递归公式中是常量。
  • @DeaconDesperado 递归公式在最后一个代码块中给出。您只需计算 W = 1..W 的这些值。对于x (1..{W-1}) 的每个可能值,sum_x(arg) 应读取为 arg 的总和。
猜你喜欢
  • 2010-12-21
  • 1970-01-01
  • 2012-05-10
  • 2021-03-23
  • 2022-06-16
  • 2020-05-17
  • 1970-01-01
  • 2012-01-04
  • 1970-01-01
相关资源
最近更新 更多