Skip to content

Commit 6bc43e4

Browse files
authored
feat: add solutions to lc problem: No.1349 (doocs#2155)
No.1349.Maximum Students Taking Exam
1 parent 6e93db1 commit 6bc43e4

File tree

3 files changed

+138
-1
lines changed

3 files changed

+138
-1
lines changed

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

+42-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
- 状态 $mask$ 不能选择 $seat$ 之外的座位;
7878
- 状态 $mask$ 不能选择相邻的座位。
7979

80-
如果满足条件,我们求出当前行选择的座位个数 $cnt$,如果当前是最后一行,则更新函数的返回值,即 $ans = max(ans, cnt)$。否则,我们继续递归地求解下一行的最大人数,下一行的座位状态 $nxt = ss[i + 1]$,并且需要排除当前行已选座位的左右两侧。然后我们递归地求解下一行的最大人数,即 $ans = max(ans, cnt + dfs(nxt, i + 1))$。
80+
如果满足条件,我们求出当前行选择的座位个数 $cnt$,如果当前是最后一行,则更新函数的返回值,即 $ans = \max(ans, cnt)$。否则,我们继续递归地求解下一行的最大人数,下一行的座位状态 $nxt = ss[i + 1]$,并且需要排除当前行已选座位的左右两侧。然后我们递归地求解下一行的最大人数,即 $ans = \max(ans, cnt + dfs(nxt, i + 1))$。
8181

8282
最后,我们将 $ans$ 作为函数的返回值返回。
8383

@@ -259,6 +259,47 @@ func maxStudents(seats [][]byte) int {
259259
}
260260
```
261261

262+
### **TypeScript**
263+
264+
```ts
265+
function maxStudents(seats: string[][]): number {
266+
const m: number = seats.length;
267+
const n: number = seats[0].length;
268+
const ss: number[] = Array(m).fill(0);
269+
const f: number[][] = Array.from({ length: 1 << n }, () => Array(m).fill(-1));
270+
for (let i = 0; i < m; ++i) {
271+
for (let j = 0; j < n; ++j) {
272+
if (seats[i][j] === '.') {
273+
ss[i] |= 1 << j;
274+
}
275+
}
276+
}
277+
278+
const dfs = (seat: number, i: number): number => {
279+
if (f[seat][i] !== -1) {
280+
return f[seat][i];
281+
}
282+
let ans: number = 0;
283+
for (let mask = 0; mask < 1 << n; ++mask) {
284+
if ((seat | mask) !== seat || (mask & (mask << 1)) !== 0) {
285+
continue;
286+
}
287+
const cnt: number = mask.toString(2).split('1').length - 1;
288+
if (i === m - 1) {
289+
ans = Math.max(ans, cnt);
290+
} else {
291+
let nxt: number = ss[i + 1];
292+
nxt &= ~(mask >> 1);
293+
nxt &= ~(mask << 1);
294+
ans = Math.max(ans, cnt + dfs(nxt, i + 1));
295+
}
296+
}
297+
return (f[seat][i] = ans);
298+
};
299+
return dfs(ss[0], 0);
300+
}
301+
```
302+
262303
### **...**
263304

264305
```

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

+60
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,25 @@
5959

6060
## Solutions
6161

62+
**Solution 1: State Compression + Memoization Search**
63+
64+
We notice that each seat has two states: selectable and non-selectable. Therefore, we can use a binary number to represent the seat state of each row, where $1$ represents selectable, and $0$ represents non-selectable. For example, for the first row in Example 1, we can represent it as $010010$. Therefore, we convert the initial seats into a one-dimensional array $ss$, where $ss[i]$ represents the seat state of the $i$th row.
65+
66+
Next, we design a function $dfs(seat, i)$, which represents the maximum number of students that can be accommodated starting from the $i$th row, and the seat state of the current row is $seat$.
67+
68+
We can enumerate all the seat selection states $mask$ of the $i$th row, and judge whether $mask$ meets the following conditions:
69+
70+
- The state $mask$ cannot select seats outside of $seat$;
71+
- The state $mask$ cannot select adjacent seats.
72+
73+
If the conditions are met, we calculate the number of seats selected in the current row $cnt$. If it is the last row, update the return value of the function, that is, $ans = \max(ans, cnt)$. Otherwise, we continue to recursively solve the maximum number of the next row. The seat state of the next row is $nxt = ss[i + 1]$, and we need to exclude the left and right sides of the selected seats in the current row. Then we recursively solve the maximum number of the next row, that is, $ans = \max(ans, cnt + dfs(nxt, i + 1))$.
74+
75+
Finally, we return $ans$ as the return value of the function.
76+
77+
To avoid repeated calculations, we can use memoization search to save the return value of the function $dfs(seat, i)$ in a two-dimensional array $f$, where $f[seat][i]$ represents the maximum number of students that can be accommodated starting from the $i$th row, and the seat state of the current row is $seat$.
78+
79+
The time complexity is $O(4^n \times n \times m)$, and the space complexity is $O(2^n \times m)$. Where $m$ and $n$ are the number of rows and columns of the seats, respectively.
80+
6281
<!-- tabs:start -->
6382

6483
### **Python3**
@@ -229,6 +248,47 @@ func maxStudents(seats [][]byte) int {
229248
}
230249
```
231250

251+
### **TypeScript**
252+
253+
```ts
254+
function maxStudents(seats: string[][]): number {
255+
const m: number = seats.length;
256+
const n: number = seats[0].length;
257+
const ss: number[] = Array(m).fill(0);
258+
const f: number[][] = Array.from({ length: 1 << n }, () => Array(m).fill(-1));
259+
for (let i = 0; i < m; ++i) {
260+
for (let j = 0; j < n; ++j) {
261+
if (seats[i][j] === '.') {
262+
ss[i] |= 1 << j;
263+
}
264+
}
265+
}
266+
267+
const dfs = (seat: number, i: number): number => {
268+
if (f[seat][i] !== -1) {
269+
return f[seat][i];
270+
}
271+
let ans: number = 0;
272+
for (let mask = 0; mask < 1 << n; ++mask) {
273+
if ((seat | mask) !== seat || (mask & (mask << 1)) !== 0) {
274+
continue;
275+
}
276+
const cnt: number = mask.toString(2).split('1').length - 1;
277+
if (i === m - 1) {
278+
ans = Math.max(ans, cnt);
279+
} else {
280+
let nxt: number = ss[i + 1];
281+
nxt &= ~(mask >> 1);
282+
nxt &= ~(mask << 1);
283+
ans = Math.max(ans, cnt + dfs(nxt, i + 1));
284+
}
285+
}
286+
return (f[seat][i] = ans);
287+
};
288+
return dfs(ss[0], 0);
289+
}
290+
```
291+
232292
### **...**
233293

234294
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
function maxStudents(seats: string[][]): number {
2+
const m: number = seats.length;
3+
const n: number = seats[0].length;
4+
const ss: number[] = Array(m).fill(0);
5+
const f: number[][] = Array.from({ length: 1 << n }, () => Array(m).fill(-1));
6+
for (let i = 0; i < m; ++i) {
7+
for (let j = 0; j < n; ++j) {
8+
if (seats[i][j] === '.') {
9+
ss[i] |= 1 << j;
10+
}
11+
}
12+
}
13+
14+
const dfs = (seat: number, i: number): number => {
15+
if (f[seat][i] !== -1) {
16+
return f[seat][i];
17+
}
18+
let ans: number = 0;
19+
for (let mask = 0; mask < 1 << n; ++mask) {
20+
if ((seat | mask) !== seat || (mask & (mask << 1)) !== 0) {
21+
continue;
22+
}
23+
const cnt: number = mask.toString(2).split('1').length - 1;
24+
if (i === m - 1) {
25+
ans = Math.max(ans, cnt);
26+
} else {
27+
let nxt: number = ss[i + 1];
28+
nxt &= ~(mask >> 1);
29+
nxt &= ~(mask << 1);
30+
ans = Math.max(ans, cnt + dfs(nxt, i + 1));
31+
}
32+
}
33+
return (f[seat][i] = ans);
34+
};
35+
return dfs(ss[0], 0);
36+
}

0 commit comments

Comments
 (0)