解题思路

seats里好座位用1表示,坏座位用0表示,那么每行都是一个二进制串,这个二进制串可以用一个对应的数(这里用十进制)来存储
bitSeats[i]:

 [["#",".","#","#",".","#"],        //0 1 0 0 1 0  -> bitSeats[0] = 18[".","#","#","#","#","."],        //1 0 0 0 0 1  -> bitSeats[1] = 33["#",".","#","#",".","#"]]        //0 1 0 0 1 0  -> bitSeats[2] = 18

定义:
m = seats.size(),行数;n = seats[0].size()列数。
那么每行座为的情况都可以用[0,2^n - 1]里的一个数来表示。
n = 8,右边为每行座位的情况,左边为十进数

0  :  00000000
1  :  00000001
2  :  00000010
3  :  00000011
4  :  00000100
5  :  00000101
6  :  00000110
7  :  00000111
8  :  00001000
9  :  00001001
10  :  00001010
11  :  00001011
12  :  00001100
13  :  00001101
14  :  00001110
15  :  00001111
16  :  00010000
17  :  00010001
18  :  00010010
19  :  00010011
20  :  00010100
21  :  00010101
22  :  00010110
23  :  00010111
......省略若干行
246  :  11110110
247  :  11110111
248  :  11111000
249  :  11111001
250  :  11111010
251  :  11111011
252  :  11111100
253  :  11111101
254  :  11111110
255  :  11111111

cnt1[i]:存储i对应二进制里多少个位为1
dp[i][j]:表示第i行在为j对应二进制的那种坐人方法时前i行最大坐学生数。
对于这段代码:

  1. for(int j = 0; j < (1<<n); j++) 这个循环遍历 2^n次,它要找到一些坐法,满足:
    1). (j & curRow) == j 这种坐法是第i行好位置的子集,就是位置是这样1100,你只能是1000,0100,0000,1100(这个违反下一条),不能1110这种没好位置也坐。
    2). !(j & (j >> 1)),不能出现两个人挨着坐

2.for(int k = 0; k < (1<<n); k++) 这个循环也遍历 2^n次,作用是当第i(curRow)行为j对应二进制的那种坐人方法时,在第i-1行(curRow的上一行)找不和它冲突的一些坐法k,来更新dp[i][j],即第i行在为j对应二进制的那种坐人方法时前i行最大坐学生数.
更新的状态转移方程是:dp[i][j] = max(dp[i][j], dp[i-1][k] + cnt1[j]);
k得满足:
1. dp[i - 1][k] != -1,第i-1k坐法合法
2. !((j >> 1) & k):第ij坐法不能有学生坐当第i-1行为k坐法时的合法学生左上角
3. !((j >> 1) & k):不能右上角

代码

class Solution {public:int maxStudents(vector<vector<char>>& seats) {int m = seats.size(), n = seats[0].size();vector<int>bitSeats(m,0);    for(int i = 0; i < m; i++){int curRow = 0;for(int j = 0; j < n; j++){curRow = curRow * 2 + (seats[i][j] == '.');}bitSeats[i] = curRow;}vector<int>cnt1( 1<<n, 0);for(int i = 1; i < (1<<n); i++) cnt1[i] = cnt1[i>>1] + (i&1);//`i`与`i>>1`位为1的个数就相差一(被右移移出的那位为1时) vector<vector<int>>dp(m+1, vector<int>(1<<n, -1));dp[0][0] = 0;for(int i = 1; i <= m; i++){int curRow = bitSeats[i-1];for(int j = 0; j < (1<<n); j++){if ((j & curRow) == j && !(j & (j >> 1))){for(int k = 0; k < (1<<n); k++){if (dp[i - 1][k] != -1 && !(j & (k >> 1)) && !((j >> 1) & k)){dp[i][j] = max(dp[i][j], dp[i-1][k] + cnt1[j]);}}}}}return *max_element(dp[m].begin(), dp[m].end());}
};

建议参考这个:
https://leetcode.com/problems/maximum-students-taking-exam/discuss/503686/A-simple-tutorial-on-this-bitmasking-problem

[leetcode周赛] 1349. 参加考试的最大学生数相关推荐

  1. LeetCode #1349. 参加考试的最大学生数 - 学到了:压缩状态动态规划、位运算、reduce()、str().count()

    赛题见:https://leetcode-cn.com/problems/maximum-students-taking-exam/ 我的解法是用递归实现广度优先搜索,结果是对的,但是太慢,超时了.这 ...

  2. mysql统计没有参加考试的学生名单_sQL SERVER,帮我编写一个存储过程,查询没有参加考试的学生名单,要求显示姓名、学号,具体请补充:...

    --学生表CREATETABLEmember(midchar(10)primarykey,mnamechar(50)notnull,);--课程表CREATETABLEcourse(fidchar(1 ...

  3. 某班期末考试科目为数学(MT)、英语(EN)和物理(PH),有最多不超过40人参加考试。请编程计算:(1)每个学生的总分和平均分;(2)每门课程的总分和平均分。

    某班期末考试科目为数学(MT).英语(EN)和物理(PH),有最多不超过40人参加考试.请编程计算:(1)每个学生的总分和平均分:(2)每门课程的总分和平均分. **输入格式要求:"%d&q ...

  4. 1、某班期末考试科目为数学(MT)、英语(EN)和物理(PH),有最多不超过30人参加考试。考试后要求:(1)计算每个学生的总分和平均分;(2)按总分成绩由高到低排出成绩的名次;(3)打印出名

    #include<iostream> #include<iomanip> using namespace std; int main() {     int a[30][6], ...

  5. 多表查询_未参加考试的学生_学生成绩档_case when then else end

    sql表 班级表class 学生表student 成绩表scores 1:查询没有参加考试(没有成绩表)的学生 SELECT s.sid,s.sname,s.sex,c.cname,sc.langua ...

  6. 第一次LeetCode周赛心得(力扣-cn周赛,使用python3)

    第一次力扣参赛:第 174 场力扣周赛 第 174 场力扣周赛赛题: https://leetcode-cn.com/circle/discuss/lEfEkb/view/OrAJAh/ 第 174 ...

  7. 我也是LeetCode周赛“三道题选手”啦 第270场周赛

    第270场周赛小结 我的Weekly Contest 270战况 什么是LeetCode周赛? show my code! 复盘解决Hard题 我的Weekly Contest 270战况 参加周赛有 ...

  8. 完成以下程序,并进行调试某班期末考试科目为数学、英语和计算机,有最多不超过30人参加考试。

    完成以下程序,并进行调试 某班期末考试科目为数学.英语和计算机,有最多不超过30人参加考试,考试后要求:1)计算每个学生的总分和平均分: 2)按总分成绩由高到低排出成绩的名次: 3)打印出名次表,表格 ...

  9. 2021年河南省高考数据统计:河南省参加考试人数占报名人数的83.7%,本土156所高校(1所211大学)

    依据河南日报信息,2021年河南省高考报名人数125万人(含参加高职单招已录取20.4万人),占全国报名人数的11.6%,实际参加考试104.6万人(含专升本省统考18.74万人.对口招生省统考6.9 ...

最新文章

  1. java负数右移_收入囊中篇---Java程序基础(二)
  2. 刚刚,阿里开源了一系列重磅技术炸弹!| 程序员必看
  3. servlet的注解开发
  4. replace使用案例--替换空格
  5. C++学习笔记-DLL中动态内存管理
  6. 语句乎?表达式乎?(Python/C)
  7. Atitit 综合原则 软件与项目开发中的理念信念 目录 1.1. 建议组合使用扬长避短 1 1.2. 常见数据库 mysql oracle mssql mongodb postgre sqlit
  8. 面试2年经验的Java程序员面试题部分带答案
  9. PHP图片与文字合成
  10. 计算机信息安全专业代码0839,全国网络空间安全学科专业分布
  11. 【转】S60 V3 常见问题解决方法...
  12. 流光快门Matlab,华为手机流光快门太好玩了!这几个特效分分钟拍出大片感
  13. 苹果将数据转存至中国服务器 或威胁国内信息安全
  14. 又一家美业SaaS+系统宣布停止服务,美业人你怎么看?
  15. Codeforces Round #644 (Div. 3) H.Binary Median
  16. docker项目切换(nginx)、重启shell 脚本
  17. 三维声场(虚拟3D音频)学习总结(1):基本概念
  18. 用matlab实现高斯信道建模
  19. 《瓦尔登湖》中的“访客”篇中一首小诗与刘禹锡的《陋室铭》
  20. 牛客网刷题笔记-SQL66 牛客每个人最近的登录日期(一)

热门文章

  1. python从入门到精通pdf清华大学出版社-python从入门到精通 清华大学出版社
  2. 怎样学好python编程-3个月学好Python有多简单?
  3. python 入门基础-如何学习Python,以及新手如何入门?
  4. python和java学哪个好-python和java自学哪个好?
  5. micropython入门教程-【ESP8266】MicroPython的快速入门教程
  6. python能做什么程序-python都能做什么
  7. python怎么读取excel-python怎么读取excel中的数值
  8. 如何自学python-小白是如何自学Python逆袭成功的?
  9. Vue前端路由~满满的干货
  10. ES6数组的扩展~超详细、超好理解哦