Skip to content

Commit 9b3537d

Browse files
committed
feat: add solutions to lc problem: No.1349
No.1349.Maximum Students Taking Exam
1 parent be76ec2 commit 9b3537d

File tree

6 files changed

+502
-2
lines changed

6 files changed

+502
-2
lines changed

solution/1300-1399/1349.Maximum Students Taking Exam/README.md

Lines changed: 183 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,22 +63,204 @@
6363

6464
<!-- 这里可写通用的实现逻辑 -->
6565

66+
**方法一:状态压缩 + 记忆化搜索**
67+
68+
我们注意到,每个座位有两种状态:可选和不可选。因此,我们可以使用二进制数来表示每一行的座位状态,其中 $1$ 表示可选,而 $0$ 表示不可选。例如,对于示例 $1$ 中的第一行,我们可以表示为 $010010$。因此,我们将初始座位转换为一个一维数组 $ss$,其中 $ss[i]$ 表示第 $i$ 行的座位状态。
69+
70+
接下来,我们设计一个函数 $dfs(seat, i)$,表示从第 $i$ 行开始,当前行的座位状态为 $seat$,可以容纳的最多学生人数。
71+
72+
我们可以枚举第 $i$ 行的所有选座状态 $mask$,并且判断 $mask$ 是否满足以下条件:
73+
74+
- 状态 $mask$ 不能选择 $seat$ 之外的座位;
75+
- 状态 $mask$ 不能选择相邻的座位。
76+
77+
如果满足条件,我们求出当前行选择的座位个数 $cnt$,如果当前是最后一行,则更新函数的返回值,即 $ans = max(ans, cnt)$。否则,我们继续递归地求解下一行的最大人数,下一行的座位状态 $nxt = ss[i + 1]$,并且需要排除当前行已选座位的左右两侧。然后我们递归地求解下一行的最大人数,即 $ans = max(ans, cnt + dfs(nxt, i + 1))$。
78+
79+
最后,我们将 $ans$ 作为函数的返回值返回。
80+
81+
为了避免重复计算,我们可以使用记忆化搜索,将函数 $dfs(seat, i)$ 的返回值保存在一个二维数组 $f$ 中,其中 $f[seat][i]$ 表示从第 $i$ 行开始,当前行的座位状态为 $seat$,可以容纳的最多学生人数。
82+
83+
时间复杂度 $O(4^n \times n \times m)$,空间复杂度 $O(2^n \times m)$。其中 $m$ 和 $n$ 分别为座位的行数和列数。
84+
6685
<!-- tabs:start -->
6786

6887
### **Python3**
6988

7089
<!-- 这里可写当前语言的特殊实现逻辑 -->
7190

7291
```python
73-
92+
class Solution:
93+
def maxStudents(self, seats: List[List[str]]) -> int:
94+
def f(seat: List[str]) -> int:
95+
mask = 0
96+
for i, c in enumerate(seat):
97+
if c == '.':
98+
mask |= 1 << i
99+
return mask
100+
101+
@cache
102+
def dfs(seat: int, i: int) -> int:
103+
ans = 0
104+
for mask in range(1 << n):
105+
if (seat | mask) != seat or (mask & (mask << 1)):
106+
continue
107+
cnt = mask.bit_count()
108+
if i == len(ss) - 1:
109+
ans = max(ans, cnt)
110+
else:
111+
nxt = ss[i + 1]
112+
nxt &= ~(mask << 1)
113+
nxt &= ~(mask >> 1)
114+
ans = max(ans, cnt + dfs(nxt, i + 1))
115+
return ans
116+
117+
n = len(seats[0])
118+
ss = [f(s) for s in seats]
119+
return dfs(ss[0], 0)
74120
```
75121

76122
### **Java**
77123

78124
<!-- 这里可写当前语言的特殊实现逻辑 -->
79125

80126
```java
127+
class Solution {
128+
private Integer[][] f;
129+
private int n;
130+
private int[] ss;
131+
132+
public int maxStudents(char[][] seats) {
133+
int m = seats.length;
134+
n = seats[0].length;
135+
ss = new int[m];
136+
f = new Integer[1 << n][m];
137+
for (int i = 0; i < m; ++i) {
138+
for (int j = 0; j < n; ++j) {
139+
if (seats[i][j] == '.') {
140+
ss[i] |= 1 << j;
141+
}
142+
}
143+
}
144+
return dfs(ss[0], 0);
145+
}
146+
147+
private int dfs(int seat, int i) {
148+
if (f[seat][i] != null) {
149+
return f[seat][i];
150+
}
151+
int ans = 0;
152+
for (int mask = 0; mask < 1 << n; ++mask) {
153+
if ((seat | mask) != seat || (mask & (mask << 1)) != 0) {
154+
continue;
155+
}
156+
int cnt = Integer.bitCount(mask);
157+
if (i == ss.length - 1) {
158+
ans = Math.max(ans, cnt);
159+
} else {
160+
int nxt = ss[i + 1];
161+
nxt &= ~(mask << 1);
162+
nxt &= ~(mask >> 1);
163+
ans = Math.max(ans, cnt + dfs(nxt, i + 1));
164+
}
165+
}
166+
return f[seat][i] = ans;
167+
}
168+
}
169+
```
170+
171+
### **C++**
172+
173+
```cpp
174+
class Solution {
175+
public:
176+
int maxStudents(vector<vector<char>>& seats) {
177+
int m = seats.size();
178+
int n = seats[0].size();
179+
vector<int> ss(m);
180+
vector<vector<int>> f(1 << n, vector<int>(m, -1));
181+
for (int i = 0; i < m; ++i) {
182+
for (int j = 0; j < n; ++j) {
183+
if (seats[i][j] == '.') {
184+
ss[i] |= 1 << j;
185+
}
186+
}
187+
}
188+
function<int(int, int)> dfs = [&](int seat, int i) -> int {
189+
if (f[seat][i] != -1) {
190+
return f[seat][i];
191+
}
192+
int ans = 0;
193+
for (int mask = 0; mask < 1 << n; ++mask) {
194+
if ((seat | mask) != seat || (mask & (mask << 1)) != 0) {
195+
continue;
196+
}
197+
int cnt = __builtin_popcount(mask);
198+
if (i == m - 1) {
199+
ans = max(ans, cnt);
200+
} else {
201+
int nxt = ss[i + 1];
202+
nxt &= ~(mask >> 1);
203+
nxt &= ~(mask << 1);
204+
ans = max(ans, cnt + dfs(nxt, i + 1));
205+
}
206+
}
207+
return f[seat][i] = ans;
208+
};
209+
return dfs(ss[0], 0);
210+
}
211+
};
212+
```
81213
214+
### **Go**
215+
216+
```go
217+
func maxStudents(seats [][]byte) int {
218+
m, n := len(seats), len(seats[0])
219+
ss := make([]int, m)
220+
f := make([][]int, 1<<n)
221+
for i, seat := range seats {
222+
for j, c := range seat {
223+
if c == '.' {
224+
ss[i] |= 1 << j
225+
}
226+
}
227+
}
228+
for i := range f {
229+
f[i] = make([]int, m)
230+
for j := range f[i] {
231+
f[i][j] = -1
232+
}
233+
}
234+
var dfs func(int, int) int
235+
dfs = func(seat, i int) int {
236+
if f[seat][i] != -1 {
237+
return f[seat][i]
238+
}
239+
ans := 0
240+
for mask := 0; mask < 1<<n; mask++ {
241+
if (seat|mask) != seat || (mask&(mask<<1)) != 0 {
242+
continue
243+
}
244+
cnt := bits.OnesCount(uint(mask))
245+
if i == m-1 {
246+
ans = max(ans, cnt)
247+
} else {
248+
nxt := ss[i+1] & ^(mask >> 1) & ^(mask << 1)
249+
ans = max(ans, cnt+dfs(nxt, i+1))
250+
}
251+
}
252+
f[seat][i] = ans
253+
return ans
254+
}
255+
return dfs(ss[0], 0)
256+
}
257+
258+
func max(a, b int) int {
259+
if a > b {
260+
return a
261+
}
262+
return b
263+
}
82264
```
83265

84266
### **...**

solution/1300-1399/1349.Maximum Students Taking Exam/README_EN.md

Lines changed: 164 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,176 @@
6464
### **Python3**
6565

6666
```python
67-
67+
class Solution:
68+
def maxStudents(self, seats: List[List[str]]) -> int:
69+
def f(seat: List[str]) -> int:
70+
mask = 0
71+
for i, c in enumerate(seat):
72+
if c == '.':
73+
mask |= 1 << i
74+
return mask
75+
76+
@cache
77+
def dfs(seat: int, i: int) -> int:
78+
ans = 0
79+
for mask in range(1 << n):
80+
if (seat | mask) != seat or (mask & (mask << 1)):
81+
continue
82+
cnt = mask.bit_count()
83+
if i == len(ss) - 1:
84+
ans = max(ans, cnt)
85+
else:
86+
nxt = ss[i + 1]
87+
nxt &= ~(mask << 1)
88+
nxt &= ~(mask >> 1)
89+
ans = max(ans, cnt + dfs(nxt, i + 1))
90+
return ans
91+
92+
n = len(seats[0])
93+
ss = [f(s) for s in seats]
94+
return dfs(ss[0], 0)
6895
```
6996

7097
### **Java**
7198

7299
```java
100+
class Solution {
101+
private Integer[][] f;
102+
private int n;
103+
private int[] ss;
104+
105+
public int maxStudents(char[][] seats) {
106+
int m = seats.length;
107+
n = seats[0].length;
108+
ss = new int[m];
109+
f = new Integer[1 << n][m];
110+
for (int i = 0; i < m; ++i) {
111+
for (int j = 0; j < n; ++j) {
112+
if (seats[i][j] == '.') {
113+
ss[i] |= 1 << j;
114+
}
115+
}
116+
}
117+
return dfs(ss[0], 0);
118+
}
119+
120+
private int dfs(int seat, int i) {
121+
if (f[seat][i] != null) {
122+
return f[seat][i];
123+
}
124+
int ans = 0;
125+
for (int mask = 0; mask < 1 << n; ++mask) {
126+
if ((seat | mask) != seat || (mask & (mask << 1)) != 0) {
127+
continue;
128+
}
129+
int cnt = Integer.bitCount(mask);
130+
if (i == ss.length - 1) {
131+
ans = Math.max(ans, cnt);
132+
} else {
133+
int nxt = ss[i + 1];
134+
nxt &= ~(mask << 1);
135+
nxt &= ~(mask >> 1);
136+
ans = Math.max(ans, cnt + dfs(nxt, i + 1));
137+
}
138+
}
139+
return f[seat][i] = ans;
140+
}
141+
}
142+
```
143+
144+
### **C++**
145+
146+
```cpp
147+
class Solution {
148+
public:
149+
int maxStudents(vector<vector<char>>& seats) {
150+
int m = seats.size();
151+
int n = seats[0].size();
152+
vector<int> ss(m);
153+
vector<vector<int>> f(1 << n, vector<int>(m, -1));
154+
for (int i = 0; i < m; ++i) {
155+
for (int j = 0; j < n; ++j) {
156+
if (seats[i][j] == '.') {
157+
ss[i] |= 1 << j;
158+
}
159+
}
160+
}
161+
function<int(int, int)> dfs = [&](int seat, int i) -> int {
162+
if (f[seat][i] != -1) {
163+
return f[seat][i];
164+
}
165+
int ans = 0;
166+
for (int mask = 0; mask < 1 << n; ++mask) {
167+
if ((seat | mask) != seat || (mask & (mask << 1)) != 0) {
168+
continue;
169+
}
170+
int cnt = __builtin_popcount(mask);
171+
if (i == m - 1) {
172+
ans = max(ans, cnt);
173+
} else {
174+
int nxt = ss[i + 1];
175+
nxt &= ~(mask >> 1);
176+
nxt &= ~(mask << 1);
177+
ans = max(ans, cnt + dfs(nxt, i + 1));
178+
}
179+
}
180+
return f[seat][i] = ans;
181+
};
182+
return dfs(ss[0], 0);
183+
}
184+
};
185+
```
73186
187+
### **Go**
188+
189+
```go
190+
func maxStudents(seats [][]byte) int {
191+
m, n := len(seats), len(seats[0])
192+
ss := make([]int, m)
193+
f := make([][]int, 1<<n)
194+
for i, seat := range seats {
195+
for j, c := range seat {
196+
if c == '.' {
197+
ss[i] |= 1 << j
198+
}
199+
}
200+
}
201+
for i := range f {
202+
f[i] = make([]int, m)
203+
for j := range f[i] {
204+
f[i][j] = -1
205+
}
206+
}
207+
var dfs func(int, int) int
208+
dfs = func(seat, i int) int {
209+
if f[seat][i] != -1 {
210+
return f[seat][i]
211+
}
212+
ans := 0
213+
for mask := 0; mask < 1<<n; mask++ {
214+
if (seat|mask) != seat || (mask&(mask<<1)) != 0 {
215+
continue
216+
}
217+
cnt := bits.OnesCount(uint(mask))
218+
if i == m-1 {
219+
ans = max(ans, cnt)
220+
} else {
221+
nxt := ss[i+1] & ^(mask >> 1) & ^(mask << 1)
222+
ans = max(ans, cnt+dfs(nxt, i+1))
223+
}
224+
}
225+
f[seat][i] = ans
226+
return ans
227+
}
228+
return dfs(ss[0], 0)
229+
}
230+
231+
func max(a, b int) int {
232+
if a > b {
233+
return a
234+
}
235+
return b
236+
}
74237
```
75238

76239
### **...**

0 commit comments

Comments
 (0)