zoukankan      html  css  js  c++  java
  • leetcode 1349--状态压缩DP

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

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

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

    每一行我们都可以用二进制位表示,1表示存在学生,0表示不存在或不能存在(#)

    那么每一行都有一个初始状态,之后每一行所有的状态都是当前状态的子集,我们用(x&y)==x表示x是否是y的子集。此外,对于每一行,我们要求相邻的元素不能相同,即(x&(x>>1))检查状态x是否有两个相邻的1

    此外,还要求前一行的左上,右上不能有相同的元素,于是有(x&(y>>1))和((x>>1)&y)表示

    我们用dp[i][j]表示前i行,当前状态为j时最大的学生数量,那么状态转移方程为dp[i][j]=max(dp[i-1][k]+invalid(j),dp[i][j]);invalid(j)表示状态j的二进制位上1的数目

    代码如下:

    int maxStudents(vector<vector<char>>& seats) {
            int m=seats.size();
            int n=seats[0].size();
            vector<vector<int>>dp(m+1,vector<int>(1<<n,-1));
            vector<int>valid;//初始每行状态
            for(int i=0;i<m;i++)
            {
                int cur=0;
                for(int j=0;j<n;j++)
                {
                    cur=cur*2+(seats[i][j]=='.');
                }
                valid.push_back(cur);
            }
            dp[0][0]=0;
            for(int i=1;i<=m;i++)
            {
                int val=valid[i-1];
                for(int j=0;j<(1<<n);j++)
                {
                    if((j&val)==j&&!(j&(j>>1)))//必须是可行状态的子集以及同一行之间不能存在相邻元素
                    {
                        for(int k=0;k<(1<<n);k++)
                        {
                            if(!(j&(k>>1))&&!((j>>1)&k)&&dp[i-1][k]!=-1)//左上和右上不能相同
                            {
                                dp[i][j]=max(dp[i][j],dp[i-1][k]+__builtin_popcount(j));//__builtin_popcount可以计算出状态j的有效位数
                            }
                        }
                    }
                }
            }
            int ans=0;
            for(int i=0;i<(1<<n);i++)
                ans=max(ans,dp[m][i]);
            return ans;
        }
  • 相关阅读:
    常用的20个正则表达式
    关于position:fixed;的居中问题
    Html table 合并单元格
    JS异步加载的三种方式
    DOM事件代码小结
    用js写一个回车键盘事件
    JavaScript 常用方法总结
    可拖拽进度条
    js数组拍平
    js验证码倒计时
  • 原文地址:https://www.cnblogs.com/flightless/p/12309522.html
Copyright © 2011-2022 走看看