1240 Tiling a Rectangle with the Fewest Squares 铺瓷砖
Problem Description
You are a construction team foreman, ready for interior decoration is unique design style house set in accordance with the requirements of designers.
House living room the size of n
the X- m
, in order to maintain the minimalist style, you need to use as few square tiles to blanket the ground.
Any specifications assume a square tile edge length are integers.
Please help designers to calculate the minimum number of blocks of square tiles need to use?
Example 1:
Input: n-= 2, m =. 3
Output: . 3
**解释:**3
a piece of land can be covered with tile bedroom.
2
Block1x1 地砖
1
Block2x2 地砖
Example 2:
Input: n-= 5, m =. 8
Output: 5
Example 3:
Input: n-=. 11, m = 13 is
output: 6
prompt:
1 <= n <= 13
1 <= m <= 13
Thinking
- Read the title
given a fixed area of the room N * M, using正方形
tiles just fill, tiles variable length, the number of tiles required minimum
Greedy thought + + exception rule out action to achieve compliance
- Greedy
per square Select division (the maximum length of the current optimal solution ), thereby to be divided into two blocks, one of which continues to select square greedy dividing the maximum length
- Regulation movable
Each block may be divided into two sub-blocks, and can continue to block cell division -> most optimal solution by merging blocks larger than a cell block
- 特例
11*13
这个区块 最优解不能完全分割成两个不相关的区块
- 一般区块的最优解分3种情况:
- N=1 或者 M=1 即只能平铺
1*1
的方块 M或N个
- N=M 直接一步到位 铺上
N*N
的方块 1个
- 其他情况 将区块横着切分或者竖着切分 找到最小的那个方案
- N=1 或者 M=1 即只能平铺
打表法
因为运算的数据量不大 13*13
可以手动生成全局答案
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
[2, 1, 3, 2, 4, 3, 5, 4, 6, 5, 7, 6, 8]
[3, 3, 1, 4, 4, 2, 5, 5, 3, 6, 6, 4, 7]
[4, 2, 4, 1, 5, 3, 5, 2, 6, 4, 6, 3, 7]
[5, 4, 4, 5, 1, 5, 5, 5, 6, 2, 6, 6, 6]
[6, 3, 2, 3, 5, 1, 5, 4, 3, 4, 6, 2, 6]
[7, 5, 5, 5, 5, 5, 1, 7, 6, 6, 6, 6, 6]
[8, 4, 5, 2, 5, 4, 7, 1, 7, 5, 6, 3, 6]
[9, 6, 3, 6, 6, 3, 6, 7, 1, 6, 7, 4, 7]
[10, 5, 6, 4, 2, 4, 6, 5, 6, 1, 6, 5, 7]
[11, 7, 6, 6, 6, 6, 6, 6, 7, 6, 1, 7, 6]
[12, 6, 4, 3, 6, 2, 6, 3, 4, 5, 7, 1, 7]
[13, 8, 7, 7, 6, 6, 6, 6, 7, 7, 6, 7, 1]
代码实现
动态规划
public class Solution {
private static int size = 13;
private static int[][] dp = new int[size + 1][size + 1];
static {
// 初始化为-1 表示没有被修改
for (int i = 1; i <= size; i++) {
Arrays.fill(dp[i], -1);
}
for (int i = 1; i <= size; i++) {
// i*1 or 1*i 面积的铺瓷砖数量
dp[i][1] = i;
dp[1][i] = i;
// i*i 面积的铺瓷砖数量
dp[i][i] = 1;
}
// 唯一的特殊情况 11*13 or 13*11 面积的铺瓷砖数量 不符合贪心规则
int specialCaseW = 11, specialCaseH = 13, specialCaseR = 6;
dp[specialCaseH][specialCaseW] = specialCaseR;
dp[specialCaseW][specialCaseH] = specialCaseR;
}
public int tilingRectangle(int n, int m) {
return helper(n, m);
}
private int helper(int n, int m) {
if (dp[n][m] != -1) {
return dp[n][m];
}
// 最大分块 n*m个1*1方块
int res = n * m, tmp;
// 横着切
for (int i = 1; i < n; i++) {
tmp = helper(i, m) + helper(n - i, m);
res = Math.min(res, tmp);
}
// 竖着切
for (int i = 1; i < m; i++) {
tmp = helper(n, i) + helper(n, m - i);
res = Math.min(res, tmp);
}
// 备忘录 n*m == m*n
dp[n][m] = dp[m][n] = res;
return res;
}
}