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 <= 131 <= 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,可以取 异或