Java實現 LeetCode 790 多米諾和托米諾平鋪(遞推)

790. 多米諾和托米諾平鋪

有兩種形狀的瓷磚:一種是 2x1 的多米諾形,另一種是形如 “L” 的托米諾形。兩種形狀都可以旋轉。

XX <- 多米諾

XX <- “L” 托米諾
X
給定 N 的值,有多少種方法可以平鋪 2 x N 的面板?返回值 mod 10^9 + 7。

(平鋪指的是每個正方形都必須有瓷磚覆蓋。兩個平鋪不同,當且僅當面板上有四個方向上的相鄰單元中的兩個,使得恰好有一個平鋪有一個瓷磚佔據兩個正方形。)

示例:
輸入: 3
輸出: 5
解釋:
下面列出了五種不同的方法,不同字母代表不同瓷磚:
XYZ XXZ XYY XXY XYY
XYZ YYZ XZZ XYY XXY
提示:

N 的範圍是 [1, 1000]

class Solution {


    //dp[i][0]是第n行,並且是平鋪
    //dp[i][1]是第n行,不平鋪的

    // public int numTilings(int N) {
    //     long[][] dp = new long[N+1][3];
    //     dp[0][0] = 1;
    //     dp[0][1] = 0;
    //     int MOD = 1000000007;
    //     for(int i = 1 ; i <= N ; ++i){
    //         long temp = i < 2 ? 0 : dp[i -2][0];
    //         dp[i][0] = (temp + dp[i-1][0] + 2 * dp[i-1][1]) % MOD;
    //         dp[i][1] = (temp +dp[i-1][1]) % MOD;
    //     }
    //     return (int)dp[N][0];
    // }

    
    public int numTilings(int N) {
         int mod = 1000000007;
        int[] dp = new int[N+3];
        dp[0] = 1;
        dp[1] = 1;
        dp[2] = 2;
        dp[3] = 5;
        for(int i = 4; i <= N; i++){
            //這裏全是平鋪的,
            //我當前這一位,可以是我上一位平鋪的+一個2*1的,
            //我可以把1*2的放到最上面,也可以放在最下面,是兩種可能,所以*2
            //還可以是我三位前的那個,因爲可以是兩個L
            //但這裏,我開頭或者結尾可能是L的,如果我們在那個基礎上加上L
            //可能會導致重複,以至於要/2,也就變成了三位前的那個*2/2==1
            dp[i] = (2*(dp[i-1] % mod) % mod + dp[i-3] % mod) % mod;
        }
        return dp[N] % mod;
    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章