【LeetCode 每日一题】1240. 铺瓷砖

312 阅读2分钟

1240. 铺瓷砖

难度:困难

时间:2023/06/08


你是一位施工队的工长,根据设计师的要求准备为一套设计风格独特的房子进行室内装修。

房子的客厅大小为 n x m,为保持极简的风格,需要使用尽可能少的 正方形 瓷砖来铺盖地面。

假设正方形瓷砖的规格不限,边长都是整数。

请你帮设计师计算一下,最少需要用到多少块方形瓷砖?

示例 1:

输入:n = 2, m = 3
输出:3
解释:3 块地砖就可以铺满卧室。
     2 块 1x1 地砖
     1 块 2x2 地砖

示例 2:

输入:n = 5, m = 8
输出:5

示例 3:

输入:n = 11, m = 13
输出:6

提示:

  • 1 <= n <= 13
  • 1 <= m <= 13

解题思路:

动态规划

class Solution {
    public int tilingRectangle(int n, int m) {
        int INF = 0x3f3f3f3f;
        int[][] dp = new int[n + 1][m + 1];
        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= m; j++){
                //如果是正方形
                if(i == j){
                    dp[i][j] = 1;
                    continue;
                }
                dp[i][j] = INF;
                //1.横切
                for(int k = 1; k < i; k++){
                    dp[i][j] = Math.min(dp[i][j], dp[k][j] + dp[i - k][j]);
                }
                //2.竖切
                for(int k = 1; k < j; k++){
                    dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[i][j - k]);
                }
                
                //3.横竖切
                for(int p = 1; p <= Math.min(i, j); p++){
                    for(int k = 1; k <= p; k++){
                        if(p - k <= 0 || j - p <= 0 || i - p + k <= 0 || j - p - k <= 0) continue;
                        dp[i][j] = Math.min(dp[i][j], dp[p - k][j - p] + 
                                                        dp[i - p + k][j - p - k] +
                                                        dp[i - p][p + k] + 2);
                    }
                }
            }
        }
        return dp[n][m];
    }
}

步骤如下:

从 [0,0] 到 [n-1,m-1] 挨个访问 n*m 二维面积空格 在每个当前 [x,y] 位置,枚举所有可能的大小,填充,继续访问,直到最后一个格子,然后回溯,继续填充下一个合法大小,直到这个过程枚举完毕 注意:

我们在枚举大小时,需要从大到小枚举,然后配合 [当前解大于最优解跳过] 这个条件进行剪枝,否则时间复杂度过不了 我们在填充面积大于1的大小时,需要提前看下需要填充的面积上是否是空白的,空白则填充,否则跳过

广度优先搜索 范围小,可以用位运算代替其中的一行内容 找到左上角第一个空位开始填写,这个正方形可大可小,填完再填后面的 BFS 找到可以立即返回这个步数 检查,m 位二进制数,可以通过 2 的 n 次方减 1 的方式遮罩 n 位连续的元素,不在首位加一个左移 k 位即可 v=(pow(2,n)-1)<<k 替换,添加的位置,每个位置都设置为 0,又原位置是 1,可以取 异或