1.题目:参加考试的最大学生数
2. 自身想法
只知道可能跟动态规划有关
座位的状态包含两种,一种是坐了,另一种是没坐。并且如果(i,j)选择坐了,那么(i,j-1)、(i,j+1)、(i+1,j-1)、(i+1,j+1)这四个点就不可以选,不然(i,j)会被暴露
然后,还是没有做出来,找不到前一个状态和后一个状态的关系
3. 官方解法
设计到位运算,刚开始有点不理解,之后按照它的代码,全部走下来就可以ok了,主要记录一下,关于代码理解过程中涉及到的点。
思路:
-
以排为单位,用
status记录这一排的状态,官解这边用了二进制,1表示坐,0表示没坐。例如:status=2,二进制就是00000010表示1的这个位置是有学生的,那么可以看出这status可以用循环变量来表示 -
某一排之间是由限制的,如
#的位置不可以有学生,以及坐了学生的位子两边不可以有学生。这个限制由isSingleRowCompliant这个函数来验证 -
排与上一排之间是由关系的,如
row排的(i,j)有学生,则row-1排的(i-1,j-1)以及(i-1,j+1)不可以有学生。这个限制由isCrossRowsCompliant这个函数来验证。isCrossRowsCompliant(status,upperStatus,n) -
关于
dp(seats,row,status)函数的作用,是表示到row排状态为status时,最大的学生数。里面会用到以上两个函数,但是用到isCrossRowsCompliant这个函数的时候,还涉及到upperStatus,也就是上一排的状态 ,这必然就会有遍历上一个状态的过程(i++),并且记录一下最大值,并返回。官解,这把这个状态对于上一个状态的最大值记录在map当中,key包含了row和status这两个点的信息,value就是当前状态status对于上个状态的最大学生数 -
最后一步,就是调用
dp(seats,m-1,i)函数
4. 小知识点
因为这边涉及到位运算,用每一位来表示座位的状态,就要涉及到求解状态中1的个数,这里用到Integer.bitCount(status);//二进制补码中1的位数,就是元素的个数来统计
文章讲述了如何通过动态规划解决一个关于考试座位分配的问题,涉及到座位状态的表示、限制条件(如相邻座位不能坐人)、使用二进制和位运算计算状态中的学生数量,以及isSingleRowCompliant和isCrossRowsCompliant辅助函数的应用。

被折叠的 条评论
为什么被折叠?



