2
int ret; // store the final result3
int m, n; // m is the height, and n is the width5
// Note: original signature is changed from n,m to m,n6
public int tilingRectangle(int m, int n) {9
this.ret = m * n; // initilize the result as m*n if cut rectangle to be all 1*1 squares11
new int[m][n]; // record the status of every location, 0 means not covered, 1 means covered12
backtrack(mat, 0); // start backtracking16
// the size means how many squares cut now17
public void backtrack(int[][] mat, int size) {19
return; // if we already have more squares than the min result, no need to go forward21
// find out the leftmost and topmost postion where is not covered yet23
for (int i = 0; i < m; i++) {24
for (int j = 0; j < n; j++) {31
if (x != -1 && y != -1) break;33
// if not found, we know that all positions are covered34
if (x == -1 && y == -1) {36
ret = Math.min(size, ret);38
int len = findWidth(x, y, mat); // find the maximum width to cut the square40
cover(x, y, len, mat, 1); // cover the current square41
backtrack(mat, size + 1);42
cover(x, y, len, mat, 0); // uncover the previous result43
len--; // decrement the square width by 148
public int findWidth(int x, int y, int[][] mat) {50
while (x + len < m && y + len < n) {51
boolean flag = true; // flag means the len is reachable52
for (int i = 0; i <= len; i++) {53
// check the right i-th column and the bottom i-th row away from (x, y)54
if (mat[x + i][y + len] == 1 || mat[x + len][y + i] == 1) {65
public void cover(int x, int y, int len, int[][] mat, int val) {66
for (int i = x; i < x + len; i++) {67
for (int j = y; j < y + len; j++) {