大挑战!状压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;
    }
};

1434. 每个人戴不同帽子的方案数(第25场双周赛最后一题)

总共有 n 个人和 40 种不同的帽子,帽子编号从 1 到 40 。

给你一个整数列表的列表 hats ,其中 hats[i] 是第 i 个人所有喜欢帽子的列表。

请你给每个人安排一顶他喜欢的帽子,确保每个人戴的帽子跟别人都不一样,并返回方案数。

由于答案可能很大,请返回它对 10^9 + 7 取余后的结果。

class Solution {
public:
    const int MOD=1e9+7;
    int numberWays(vector<vector<int>>& hats) {
        int n=hats.size();
        vector<int> dp(1<<n,0);
        dp[0]=1;
        vector<set<int>> myset(41);
        for(int i=0;i<n;i++){
            for(int x:hats[i])
                myset[x].insert(i);
        }
        for(int i=1;i<=40;i++){
            for(int state=(1<<n)-1;state>=0;state--){
                for(int people:myset[i]){
                    if((state & (1<<people)))continue;
                    int nextState=state+(1<<people);
                    dp[nextState]+=dp[state];
                    dp[nextState]%=MOD;
                }
            }
        }
        return dp[(1<<n)-1];
    }
};
原文地址:https://www.cnblogs.com/Dancing-Fairy/p/12826787.html