给定一个整数N,我们可以用3 x 1个瓷砖平铺4 x N矩形的方式有多少?

时间:2014-03-05 07:57:36

标签: algorithm dynamic-programming

我知道平铺问题并不少见,它们通常通过动态编程解决。我也读过非常类似的问题here关于使用2X1瓦片平铺3XN矩形但我仍然有问题找出重复关系。

现在我知道你可以用3种方式标题4X3矩形和3X1标题。所以这里有一个关系,如f(n)= 3 * f(n-3)+ [other]。我现在已经摸不着头脑,想知道“其他”部分应该是什么。一些帮助将不胜感激。

3 个答案:

答案 0 :(得分:2)

我认为你不能轻易得到一个封闭形式的解决方案,而是你可以做一点掩码DP,它取得最后一个4x3块的状态,第一列未完成。

你无法获得封闭形式溶胶的原因是因为像这些倾斜

 ======
 ||===|
 ||===|
 ||===|

根据您放置的下一个图块,您的位掩码将会改变,您将能够获得某种递归算法。您可以在此处阅读有关位掩码DP的更多信息

http://www.quora.com/Algorithms/How-can-we-cover-an-MxN-area-with-minimum-cost-from-a-set-of-tiles-having-different-dimensions-and-different-cost

答案 1 :(得分:2)

按照您发布的链接,我尝试重建递归关系,使其适合4XN矩形和3X1平铺,这就是我所拥有的:

********   AAA*******   BBB******   A*******
******** = BBB******* + A******** + A*******
********   CCC*******   A********   A*******
********   DDD*******   A********   BBB*****
  f(n)   =  f(n-3)    +  g(n-1)  +  g(n-1)

********   AB*******   AAA******   ABBB******
********   AB*******   BBB******   ACCC******
******** = AB******* + CCC****** + ADDD******
  ******     *******     *******     ********
  g(n)   =   f(n-2)  +   h(n-2)  +   i(n-2)

********   AAA******   
 *******    ********   
 ******* =  ******** 
 *******    ********  
  h(n)   =   g(n-1)  

********   AAA******   
  ******     *******   
  ****** =   *******
  ******     *******  
  i(n)   =   j(n-2) 

  ******     *******    ********   
 *******    A*******   AAA******
 ******* =  A******* + BBB******
 *******    A*******   CCC******
  j(n)   =   f(n-1)      i(n-1)

从那我们得到:

f(n) = f(n-3) + 2*g(n-1)
g(n) = f(n-2) + h(n-2) + i(n-2)   ==>   g(n) = f(n-2) + g(n-3) + i(n-2)
h(n) = g(n-1)
i(n) = j(n-2)
j(n) = f(n-1) + i(n-1)

这些功能的停止条件是:

f(0) = 1, f(1) = 0, f(2) = 0
g(0) = 0, g(1) = 1, g(2) = 1
i(0) = 0, i(1) = 0 
j(0) = 0 

希望这有帮助!

答案 2 :(得分:1)

为了证明复发是正确的,你需要像罗恩那样计算出案例,但如果你只是想知道实验是什么,那么一些术语(取决于复发的程度)就足够了。前几个是1,3,13,57,249,1087,4745。然后你可以用线性代数求解系数。

[ 1  3  13] [x]   [  57]
[ 3 13  57] [y] = [ 249]
[13 57 249] [z]   [1087]

解决方案是x = 1且y = -3且z = 5.我们现在可以验证57 - 3 * 249 + 5 * 1087 = 4745和OEIS confirms(另一个很好的资源)重现实际上是T(N)= 5T(N-1)-3T(N-2)+ T(N-3)。这是我使用的Python代码。

import numpy
memo = {frozenset(): 1}

def memoized_ntilings(s, k=3):
    if (s in memo):
        return memo[s]
    (x, y) = min(s)
    n = 0
    h = frozenset((((x + i), y) for i in range(k)))
    if h.issubset(s):
        n += memoized_ntilings((s - h), k)
    v = frozenset(((x, (y + i)) for i in range(k)))
    if v.issubset(s):
        n += memoized_ntilings((s - v), k)
    memo[s] = n
    return n

def ntilings(n, m=4):
    return memoized_ntilings(frozenset(((x, y) for x in range(n) for y in range(m))))

def fibonacci(n):
    (a, b) = (0, 1)
    for i in range(n):
        (a, b) = (b, (a + b))
    return a

def guess_recurrence(callable):
    degree = 1
    while True:
        ab = numpy.array([[callable((i + j)) for i in range((degree + 2))] for j in range((degree + 5))])
        a = ab[:, :(- 1)]
        b = ab[:, (- 1)]
        result = numpy.linalg.lstsq(a, b)
        x = result[0]
        residuals = result[1]
        if (numpy.linalg.norm(residuals) < (1e-12 * numpy.linalg.norm(b))):
            return x
        degree += 1
if (__name__ == '__main__'):
    print(guess_recurrence(fibonacci))
    print(guess_recurrence((lambda n: ntilings((n * 3)))))

输出如下。

[ 1.  1.]
[ 1. -3.  5.]