題目鏈接
題意:
讓你給學生安排座位,有’#'號的不能坐,每個學生能看到左右和左上右上四個方向的人的試卷,請你給學生們安排座位使得學生人數最多
思路
經典的狀態壓縮dp問題,觀察到n和m最大隻有8,很明顯可以利用二進制來確定第一行的狀態,只要第一行定了剩下幾行也就定的,最後維護最一行的最大值即可。
表示第爲第個狀態時的最大值,狀態轉移方程如下:
需要注意的是要提前處理好每一行不能坐的位置。
class Solution:
def CountBinary(self, num):
_ = 0
while num:
if num & 1:
_ += 1
num = num >> 1
return _
def maxStudents(self, seats: List[List[str]]) -> int:
m, n = len(seats), len(seats[0])
mp = [0]*m
for i in range(m):
for j in range(n):
if seats[i][j] == '#':
mp[i] += (1 << j)
num = []
sta = []
for i in range(2**n):
if not ((i & (i << 1)) and (i & (i >> 1))):
num.append(self.CountBinary(i))
sta.append(i)
dp = [[0]*(2**n) for i in range(m)]
for i in range(len(num)):
if not (sta[i] & mp[0]):
dp[0][sta[i]] = num[i]
for i in range(1, m):
for j in range(len(num)):
if sta[j] & mp[i]:
continue
#if sta[j] & (sta[j] >> 1) and sta[j] & (sta[j] << 1):
# continue
for k in range(len(num)):
if sta[k] & mp[i - 1]:
continue
if (sta[j] & (sta[k] >> 1)) or (sta[j] & (sta[k] << 1)):
continue
dp[i][sta[j]] = max(dp[i][sta[j]], dp[i - 1][sta[k]] + num[j])
return max(dp[-1])