首頁 > 後端開發 > Golang > 主體

如何計算 1x1、1x2、2x1 瓷磚的可能組合有多少種可以填充 2 x N 地板?

WBOY
發布: 2024-02-10 08:54:08
轉載
397 人瀏覽過

如何计算 1x1、1x2、2x1 瓷砖的可能组合有多少种可以填充 2 x N 地板?

php小編新一將為大家解答一個有趣而燒腦的問題:如何計算 1x1、1x2、2x1 磁磚的可能組合有多少種可以填滿 2 x N 地板?這個問題涉及組合數學和動態規劃的知識,透過分析和推導,我們可以得到一個簡潔而有效的計算方法。接下來,讓我們一起來探索這個問題的答案吧!

問題內容

我剛剛做了一個技術測試,並對這個任務感到困惑。我的目標是了解如何解決這個「覆蓋地板」問題。老實說,我不知道從哪裡開始。

任務是:

  1. 有一層 2 x n 層。
  2. 我們有 1x1、1x2、2x1 的磁磚來填滿地板。

問題是:

  1. solution(1) 預期輸出為 2,實際輸出為 2。
  2. 但是,solution(2) 預期輸出為 7,實際輸出為 3。

目前的解決方案是:

  1. 1x1 總是可以填滿 2 x n 層,因此可能的方式從 1 開始。
  2. 如果剩餘樓層 mod 2 為 0,則可能的方式增加 1。

目前解決方案的問題是它不區分 1x2 和 2x1 區塊。因此對於 solution(2) 實際輸出是 3 而不是 7。

程式碼

package main

import "fmt"

// Solution is your solution code.
func Solution(n int) int {
    possibleWays := 1

    floorArea := 2 * n
    // Your code starts here.

    for i := floorArea - 1; i >= 0; i-- {
        residualFloorArea := floorArea - i
        fmt.Println(i, residualFloorArea)
        if residualFloorArea%2 == 0 {
            fmt.Println("punch")
            possibleWays += 1
        }
    }

    return possibleWays
}

func main() {
    fmt.Println(Solution(1))
    fmt.Println("next")
    fmt.Println(Solution(2))
}
登入後複製

解決方法

更具描述性且詳盡的嘗試:

呼叫覆蓋2xn網格的方式數為x_n,覆蓋2xn 1網格的方式數為y_n,覆蓋2xn 2網格的方式數為z_n。

基本案例:

  • x_0 = 1,y_0 = 1,z_0 = 2
  • x_1 = 2,y_1 = 3,z_1 = 5

歸納步驟,n >=2:

-- --
      |  |  |
 -- -- -- --  ...
|xx|  |  |  |
 -- -- -- --
登入後複製

考慮 2xn 2 網格的最左邊的單元格,如果它被 1x1 瓦片覆蓋,那麼剩下的就是 2xn 1 網格,否則,它被 1x2 瓦片覆蓋,剩下的就是 2xn 網格。因此,

z_n = x_n y_n

-- --
   |  |  |
 -- -- --  ...
|xx|  |  |
 -- -- --
登入後複製

考慮2xn 1 網格的最左邊的單元格,如果它被1x1 瓦片覆蓋,剩餘的將是2xn 網格,否則,它被1x2 瓦片覆蓋,剩餘的將是2x(n- 1) 1 格。因此,

y_n = x_n y_(n-1)

-- --
|xx|  |
 -- --  ...
|  |  |
 -- --
登入後複製

考慮2xn 網格的左上角,如果它被1x1 的圖塊覆蓋,則剩餘的將是2x(n-1) 1 個網格,如果它被1x2 的圖塊覆蓋,則剩餘的將是一個2x(n-2) 2 個網格,否則,它被2x1 瓦片覆蓋,剩餘的將是2x(n-1) 網格。因此:

x_n = y_(n-1) z_(n-2) x_(n-1)

將 z_n 替換為 x_n y_n,我們有:

  • x_n = x_(n-1) x_(n-2) y_(n-1) y_(n-2)
  • y_n = x_n y_(n-1)

現在,只需迭代計算每個值:

package main

import "fmt"

// Solution is your solution code.
func Solution(n int) int {
    if n == 0 {
        return 1
    } else if n == 1 {
        return 2
    }

    x := make([]int, n + 1)
    y := make([]int, n + 1)
    x[0] = 1
    y[0] = 1
    x[1] = 2
    y[1] = 3

    for i := 2; i <= n; i++ {
        x[i] = x[i - 1] + x[i - 2] + y[i - 1] + y[i - 2]
        y[i] = x[i] + y[i - 1]
    }

    return x[n]
}

func main() {
    fmt.Println(Solution(1))
    fmt.Println("next")
    fmt.Println(Solution(2))
}
登入後複製

您可以不使用切片來完成此操作,但這更容易理解。 遊樂場示範

以上是如何計算 1x1、1x2、2x1 瓷磚的可能組合有多少種可以填充 2 x N 地板?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:stackoverflow.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!