• 【经典】带障碍的铺砖块——LEETCODE 覆盖


    很经典的题,但是好久没做这类有点忘了。。

    经典状压dp做法:用S表示一行的状态,某位为1表示该位被占用,反之表示该位未被占用

    dp[i][S]表示第i行状态为S时的最大覆盖数,那么枚举第i-1行的状态S',如果S,S'都合法,那么此时可以求出S状态下最多可以放多少块砖

    预处理出cnt[S1][S2]表示上一行是S1,下一行是S2情况下,S2上的最大填放数,填放策略:先放竖的再放横的

    然后dp时对于两个状态就可以o(1)转移了

    二分图做法:进行黑白染色,每个地板抽象成一个点,黑白格分成两部分

    显然可以在相邻两个地板之间连边,如果是障碍物就不能连,匈牙利算法找下最大匹配即可

    class Solution {
    public:
       
        int cnt[1<<8][1<<8];
        int mp[100][100],block[100];
        void prework(int m){
            for(int S1=0;S1<(1<<m);S1++)
            for(int S2=0;S2<(1<<m);S2++){//上下状态为S1 S2时下放最多填放数量 
                int num=0,T=S2;
                for(int i=0;i<m;i++)//把竖的填了 
                    if(!(S1>>i & 1) && (T>>i & 1))num++,T-=(1<<i); 
                for(int i=0;i<m-1;i++)
                    if((T>>i&1) && (T>>(i+1)&1)){
                        num++;
                        i++;
                    } 
                cnt[S1][S2]=num;
            }
        }
        
        int dp[50][1<<8];
        int domino(int n, int m, vector<vector<int>>& broken) {
            prework(m);
            for(auto v:broken)mp[v[0]][v[1]]=1;
            for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                if(mp[i][j])block[i]|=(1<<j);
                
            memset(dp,-1,sizeof dp);    
            
            for(int i=0;i<n;i++){
                for(int S=0;S<(1<<m);S++){
                    int f=0;
                    for(int j=0;j<m;j++)
                        if(!(S>>j & 1) && mp[i][j])f=1;
                    if(f)continue;
                    
                    int T=S-block[i];//状态S可以自由填放的格子
                    if(i==0)
                        dp[i][S]=max(dp[i][S],cnt[(1<<m)-1][T]);    
                    else {
                        for(int S2=0;S2<(1<<m);S2++)
                            if(dp[i-1][S2]!=-1)
                                dp[i][S]=max(dp[i][S],dp[i-1][S2]+cnt[S2][T]); 
                    }
                }
            }
            
            int res=0;
            for(int i=0;i<(1<<m);i++)
                res=max(res,dp[n-1][i]);
            return res;
        }
    };
  • 相关阅读:
    Jupyter 魔术命令(magic commands)
    Matplotlib中plt.rcParams用法(设置图像细节)
    Neural Networks and Deep Learning(week4)Building your Deep Neural Network: Step by Step
    C语言上机复习(一)文件操作
    Neural Networks and Deep Learning(week4)深层神经网络(Deep Neural Networks)
    maven pom.xml几个特殊的插件
    maven pom.xml中的 build说明
    pom.xml的继承、聚合与依赖
    eclipse自动补全设置
    maven insall跳过测试
  • 原文地址:https://www.cnblogs.com/zsben991126/p/13039541.html
Copyright © 2020-2023  润新知