leetcode 1240. 铺瓷砖(回溯,DFS)

题目链接

https://leetcode-cn.com/problems/tiling-a-rectangle-with-the-fewest-squares/

题意:

用尽可能少的正方形瓷砖来铺地板

思路:

按行递推,每一行的情况扫完之后统计下一行的所有情况
每次填补前判断是否之前已经有瓷砖填上了

难点在于:怎么记录填补一个正方形后,剩余地板的状态信息
(其实不用每次记录剩下的信息,只是下次填剩下的地板时判断一下有没有被填过即可)

class Solution {
public:
// https://leetcode.com/problems/tiling-a-rectangle-with-the-fewest-squares/discuss/414979/Java-back-tracking-solution
    //怎么表示分割之后剩下的状态
    int ans=INT_MAX;
    int vis[14][14];
    //回溯
    void solve(int r,int c,int n,int m,int cnt){
        if(cnt>ans) return;
        if(r>=n) {
            ans=min(cnt,ans);
            return ;
        }
        if(c>=m){
            solve(r+1,0,n,m,cnt);
            return ;
        }
        if(vis[r][c]) solve(r,c+1,n,m,cnt);

        for(int k=min(n-r,m-c);k>0 && check(r,c,k);k--){
            //染色k
            col(r,c,k,1);
            solve(r,c+k,n,m,cnt+1);//按行扫描
            col(r,c,k,0);//回溯
        }
    }
    bool check(int r,int c,int k){
        for(int i=0;i<k;i++){
            for(int j=0;j<k;j++){
                if(vis[r+i][c+j]) return false;
            }
        }
        return true;
    }
    void col(int r,int c,int k,int colo){
        for(int i=0;i<k;i++){
            for(int j=0;j<k;j++){
                vis[r+i][c+j]=colo;
            }
        }
    }
    int tilingRectangle(int n, int m){
        solve(0,0,n,m,0);
        return ans;
    }
    // int dp[14][14]={0};
    // int tilingRectangle(int n, int m) {
        // if(n==0 || m==0) return 0;
        // if(n==m) return dp[n][m]=1;
        // if(dp[n][m]) return dp[n][m];

        // int ans=INT_MAX;
        // //按行覆盖,每次的步长前进为1
        // for(int x=min(n,m);x>0;x--){
        //     ans=min(ans,1+tilingRectangle(n-x,x)+tilingRectangle(n,m-x));//交错的情况,严格来说不对。。
        // } 

        // dp[n][m]=ans;
        // return ans;
    // }
};
posted @ 2020-12-11 00:44  xzhws  阅读(364)  评论(0编辑  收藏  举报