zoukankan      html  css  js  c++  java
  • LCP 4. 覆盖

    题目链接

    题解:

    我们可以对棋盘进行黑白染色,使得任意相邻的两个格子颜色不相同,然后进行二分图最大匹配。

     Code:

     1 class Solution {
     2 public:
     3     int N;
     4     int M;
     5 
     6     vector<vector<int>> dir{{1,0},{0,1},{-1,0},{0,-1}};
     7 
     8     int domino(int n, int m, vector<vector<int>>& broken) {
     9         N=n;
    10         M=m;
    11         vector<vector<int>> grid(N*M,vector<int>(N*M,0));
    12         vector<int> bro(N*M,0);
    13         for(auto b:broken){
    14             bro[b[0]*M+b[1]]=1;
    15         }
    16         for(int i=0;i<N*M;++i){
    17             if(bro[i]) continue;
    18             int x=i/M;
    19             int y=i%M;
    20             if((x+y)%2!=0) continue;
    21             for(int d=0;d<4;++d){
    22                 int nx=x+dir[d][0];
    23                 int ny=y+dir[d][1];
    24                 if(nx<0 || nx>=N || ny<0 || ny>=M || bro[nx*M+ny]) continue;
    25                 grid[i][nx*M+ny]=1;
    26             }
    27         }
    28         vector<int> mat(N*M,-1);
    29         int res=0;
    30         for(int i=0;i<N*M;++i){
    31             if(bro[i]) continue;
    32             int x=i/M;
    33             int y=i%M;
    34             if((x+y)%2==0){
    35                 vector<int> visited(N*M,0);
    36                 if(dfs(i,grid,visited, mat)){
    37                     res++;
    38                 }
    39             }
    40         }
    41         return res;
    42     }
    43 
    44     bool dfs(int u, vector<vector<int>> &grid, vector<int> &visited, vector<int> &mat){
    45         for(int i=0;i<M*N;++i){
    46             if(grid[u][i]){
    47                 if(!visited[i]){
    48                     visited[i]=1;
    49                     if(mat[i]==-1 || dfs(mat[i],grid,visited,mat)){
    50                         mat[i]=u;
    51                         return true;
    52                     }
    53                 }
    54             }
    55         }
    56         return false;
    57     }
    58 };

    用最大流做:

     1 class Solution {
     2 public:
     3     int N;
     4     int M;
     5     int S;
     6     int T;
     7     vector<vector<int>> dir{{1,0},{0,1},{-1,0},{0,-1}};
     8 
     9     int domino(int n, int m, vector<vector<int>>& broken) {
    10         N=n;
    11         M=m;
    12         S=M*N;
    13         T=M*N+1;
    14         vector<vector<int>> grid(N*M+3,vector<int>(N*M+3,0)); //残余容量
    15         vector<int> bro(N*M,0);
    16         for(auto b:broken){
    17             bro[b[0]*M+b[1]]=1;
    18         }
    19         for(int i=0;i<N*M;++i){
    20             if(bro[i]) continue;
    21             int x=i/M;
    22             int y=i%M;
    23             if((x+y)%2!=0){
    24                 grid[i][T]=1;
    25                 continue;
    26             }
    27             grid[S][i]=1;
    28             for(int d=0;d<4;++d){
    29                 int nx=x+dir[d][0];
    30                 int ny=y+dir[d][1];
    31                 if(nx<0 || nx>=N || ny<0 || ny>=M || bro[nx*M+ny]) continue;
    32                 grid[i][nx*M+ny]=1;
    33             }
    34         }
    35         int res=0;
    36         
    37         while(true){
    38             vector<int> pre(N*M+3,-1);
    39             bfs(grid,pre);
    40             
    41             if(pre[T]==-1) break;
    42             int minflow=INT_MAX;
    43             int v=T;
    44             while(true){
    45                 int u=pre[v];
    46                 minflow=min(minflow,grid[u][v]);
    47                 if(u==S) break;
    48                 v=u;
    49             }
    50             v=T;
    51             while(true){
    52                 int u=pre[v];
    53                 grid[u][v]-=minflow;
    54                 grid[v][u]+=minflow;
    55                 if(u==S) break;
    56                 v=u;
    57             }
    58             res+=minflow;
    59         }
    60 
    61         return res;
    62     }
    63 
    64     void bfs(vector<vector<int>> &grid, vector<int> &pre){
    65         queue<int> q;
    66         vector<int> visited(N*M+3,0);
    67         visited[S]=1;
    68         q.push(S);
    69         while(!q.empty()){
    70             int cur=q.front();
    71             q.pop();
    72             if(cur==T) break;
    73             for(int i=0;i<N*M+3;++i){
    74                 if(grid[cur][i]>0 && visited[i]==0){
    75                     visited[i]=1;
    76                     q.push(i);
    77                     pre[i]=cur;
    78                 }
    79             }
    80         }
    81     }
    82 };

    状压DP:

    class Solution {
    public:
        int M;
        int N;
        int domino(int n, int m, vector<vector<int>>& broken) {
            M=n;
            N=m;
            vector<int> b(n,0);
            for(auto bro:broken){
                b[bro[0]]|=(1<<bro[1]);
            }
            
            vector<vector<int>> dp(n,vector<int>(1<<(N+N),-1));
            return dfs(0,dp,b,0);
        }
    
        int dfs(int state, vector<vector<int>> &dp, vector<int> &b, int row){
            if(dp[row][state]!=-1) return dp[row][state];
            int res=0;
            for(int j=0;j<N-1;++j){
                if(((1<<j)&b[row])==0 && ((1<<(j+1))&b[row])==0 && ((1<<j)&state)==0 && ((1<<(j+1))&state)==0){
                    int ns=state|(1<<j)|(1<<(j+1));
                    res=max(res,1+dfs(ns,dp,b,row));
                }
            }
            if(row+1<M){
                for(int j=0;j<N;++j){
                    if(((1<<j)&b[row])==0 && ((1<<j)&b[row+1])==0 && ((1<<j)&state)==0 && ((1<<(j+N))&state)==0 ){
                        int ns=state|(1<<j)|(1<<(j+N));
                        res=max(res,1+dfs(ns,dp,b,row));
                    }
                }
    
                int ns=state>>N;
                
                res=max(res,dfs(ns,dp,b,row+1));
            }
            return dp[row][state]=res;
        }
    };
  • 相关阅读:
    python 给文件批量加‘“’ ”,"
    ubuntu 编译android 源码笔记
    ubuntu java 环境配置
    Android4.4r1(KitKat)源码下载地址
    android 学习视频汇总
    Java 注解
    Linux 索引节点(inode)详解
    系统启动
    Win7、Ubuntu双系统正确卸载Ubuntu系统
    深入理解LInux内核-进程通信
  • 原文地址:https://www.cnblogs.com/FEIIEF/p/12251087.html
Copyright © 2011-2022 走看看