我的形状由8x8方块构成。我需要使用最小数量的8x8,16x16,32x32和64x64的正方形来平铺它们。布置在正方形中的四个8x8正方形可以替换为单个16x16正方形,例如:
可以用什么算法来实现这个目标?
答案 0 :(得分:3)
这需要动态编程解决方案。我假设我们有一个square[r][c]
布尔数组,如果(r, c)
具有1x1平方(我已经简化了解决方案以使用1x1,2x2,4x4和8x8方块以使其更容易)遵循,但它很容易适应)。在顶行和左列填充false
sentinel values的墙。
定义一个2d count
数组,其中count[r][c]
指的是(r, c)
上方和左侧区域中1x1平方的数量。我们可以使用dp算法添加它们:
count[0..n][0..m] = 0
for i in 1..n:
for j in 1..m:
count[i][j] = count[i-1][j] + count[i][j-1] -
count[i-1][j-1] + square[i][j]
上述工作通过将我们已知的两个区域相加,减去双重计算区域并添加新单元格。使用count
数组,我们可以使用类似的方法测试方形区域是否在恒定时间内完全覆盖1x1个方块:
// p1 is the top-left coordinate, p2 the bottom-right
function region_count(p1, p2):
return count[p1.r][p1.c] - count[p1.r][p2.c-1] -
count[p2.r-1][p1.c] + 2*count[p2.r-1][p2.c-1]
然后我们创建第二个2d min_squares
数组,其中min_squares[r][c]
指的是覆盖原始1x1正方形所需的最小平方数。可以使用另一个dp:
min_squares = count
for i in 1..n:
for j in 1..m:
for size in [2, 4, 8]:
if i >= size and j >= size and
region_count((i-size, j-size), (i, j)) == size*size:
min_squares[i][j] = min(min_squares[i][j],
min_squares[i-size-1][j] +
min_squares[i][j-size-1] -
min_squares[i-size-1][j-size-1] +
1)
为了重建获得计算最小值所需的平铺,我们使用辅助size_used[r][c]
数组,我们用它来跟踪放置在(r, c)
的方形大小。从这里我们可以递归地重建平铺:
function reconstruct(i, j):
if i < 0 or j < 0:
return
place square of size size_used[i][j] at (i-size_used[i][j]+1, j-size_used[i][j]+1)
reconstruct(i-size_used[i][j], j)
reconstruct(i, j-size_used[i][j])
答案 1 :(得分:1)
您可能需要查看Optimal way for partitioning a cell based shape into a minimal amount of rectangles - 如果我理解正确,这是同样的问题,但对于矩形而不是正方形。