# 1240. Tiling a Rectangle with the Fewest Squares ###### tags: `Leetcode` `Hard` `Dynamic Programming` `Backtracking` Link: https://leetcode.com/problems/tiling-a-rectangle-with-the-fewest-squares/description/ ## 思路 把一开始的解法放在最后面了 那种解法只对要吗就横着切要吗就竖着切的有效 这个case就无效了 ![](https://i.imgur.com/goV56zW.png) 思路[参考](https://leetcode.com/problems/tiling-a-rectangle-with-the-fewest-squares/solutions/417654/6ms-clean-java-backtrack-solution-with-detailed-explanation/) backtracking填满board 每次找到leftmost topmost还没被填满的点 然后试着放所有possible size的square 再接着往下backtracking ## Code ```java= class Solution { int ans, m, n; public int tilingRectangle(int m, int n) { this.m = m; this.n = n; ans = n*m; int[][] board = new int[m][n]; backtracking(board, 0); return ans; } private void backtracking(int[][] board, int curr){ if(curr > ans) return; int x = -1, y = -1; for(int i=0; i<m; i++){ for(int j=0; j<n; j++){ if(board[i][j]==0){ x=i; y=j; break; } } if(x!=-1 && y!=-1) break; } if(x==-1 && y==-1) ans = Math.min(ans, curr); else{ int len = findLen(x, y, board); for(int i=1; i<=len; i++){ cover(x, y, i, board, 1); backtracking(board, curr+1); cover(x, y, i, board, 0); } } } private int findLen(int x, int y, int[][] board){ int len = 1; while(x+len<m && y+len<n){ boolean flag = false; for(int i=0; i<=len; i++){ if(board[x+len][y+i]==1 || board[x+i][y+len]==1){ flag = true; break; } } if(flag) break; len++; } return len; } private void cover(int x, int y, int len, int[][] board, int num){ for(int i=x; i<x+len; i++){ for(int j=y; j<y+len; j++){ board[i][j] = num; } } } } ``` 一开始的解法 ```java= class Solution { public int tilingRectangle(int n, int m) { int[][] dp = new int[n+1][m+1]; return dfs(n, m, dp); } private int dfs(int n, int m, int[][] dp){ if(dp[n][m]!=0) return dp[n][m]; if(n==m) return dp[m][n] = 1; int ans = Integer.MAX_VALUE; for(int i=1; i<=Math.min(m,n); i++){ if(n>m) ans = Math.min(ans, dfs(n-i, m, dp)+dfs(i, m, dp)); else ans = Math.min(ans, dfs(n, m-i, dp)+dfs(n, i, dp)); } return dp[n][m] = ans; } } ```