[Leetcode week race 160] 1240 tiling

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 nthe 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
**解释:**3a piece of land can be covered with tile bedroom.
2Block 1x1 地砖
1Block2x2 地砖

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这个区块 最优解不能完全分割成两个不相关的区块

dp公式

  • 一般区块的最优解分3种情况:
    1. N=1 或者 M=1 即只能平铺1*1的方块 M或N个
    2. N=M 直接一步到位 铺上N*N的方块 1个
    3. 其他情况 将区块横着切分或者竖着切分 找到最小的那个方案

打表法

因为运算的数据量不大 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;
    }
}

参考资源

第 160 场周赛 全球排名
力扣周赛录屏-leetcode-weekly-contest-160

Guess you like

Origin www.cnblogs.com/slowbirdoflsh/p/11823525.html