其他分享
首页 > 其他分享> > 大挑战!状压dp!

大挑战!状压dp!

作者:互联网

1349. 参加考试的最大学生数

给你一个 m * n 的矩阵 seats 表示教室中的座位分布。如果座位是坏的(不可用),就用 '#' 表示;否则,用 '.' 表示。

学生可以看到左侧、右侧、左上、右上这四个方向上紧邻他的学生的答卷,但是看不到直接坐在他前面或者后面的学生的答卷。请你计算并返回该考场可以容纳的一起参加考试且无法作弊的最大学生人数。

学生必须坐在状况良好的座位上。

 

class Solution {
public:
    int count(int n){
        int ans=0;
        while(n){
            ans+=(n&1);
            n>>=1;
        }
        return ans;
    }   //计算入座学生数
    bool isValid(vector<char>& row, int k){
        int i=row.size()-1;
        while(k){
            if(row[i]=='#' && (k&1)==1)return false;
            k>>=1;i--;
        }
        return true;
    }   //判断座位是否合法
    int maxStudents(vector<vector<char>>& seats) {
        int m = seats.size() , n = seats[0].size();
        vector<vector<int>> dp(m,vector<int>(1<<n,-1));
        for(int i=0;i<m;i++){
            for(int j=0;j<(1<<n);j++){
                if((j&(j<<1))!=0||(j&(j>>1))!=0||!isValid(seats[i],j))continue;
                if(i==0){
                    dp[i][j]=count(j);
                }
                else{
                    for(int k=0;k<(1<<n);k++){
                        if(dp[i-1][k]!=-1){
                            if((j&k>>1)==0&&(j&k<<1)==0)
                                dp[i][j]=max(dp[i][j],dp[i-1][k]+count(j));
                        }
                    }
                }
            }
        }
        int res=0;
        for(int i=0;i<(1<<n);i++){
            res=max(res,dp[m-1][i]);
        }
        return res;
    }
};

 

标签:int,挑战,状压,学生,vector,ans,seats,dp,row
来源: https://www.cnblogs.com/Dancing-Fairy/p/12826787.html