Skip to content

Commit f047032

Browse files
committed
feat: add solutions to lc problem: No.1900
No.1900.The Earliest and Latest Rounds Where Players Compete
1 parent a70fbdb commit f047032

File tree

7 files changed

+936
-74
lines changed

7 files changed

+936
-74
lines changed

solution/1900-1999/1900.The Earliest and Latest Rounds Where Players Compete/README.md

Lines changed: 325 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -82,41 +82,341 @@ tags:
8282

8383
<!-- solution:start -->
8484

85-
### 方法一
85+
### 方法一:记忆化搜索 + 二进制枚举
86+
87+
我们定义一个函数 $\text{dfs}(l, r, n)$,表示在当前回合中,编号为 $l$ 和 $r$ 的运动员在 $n$ 名运动员中比拼的最早和最晚回合数。
88+
89+
函数 $\text{dfs}(l, r, n)$ 的执行逻辑如下:
90+
91+
1. 如果 $l + r = n - 1$,说明两名运动员在当前回合中比拼,返回 $[1, 1]$。
92+
2. 如果 $f[l][r][n] \neq 0$,说明之前已经计算过这个状态,直接返回结果。
93+
3. 初始化最早回合数为正无穷大,最晚回合数为负无穷大。
94+
4. 计算当前回合中前半部分的运动员数目 $m = n / 2$。
95+
5. 枚举前半部分的所有可能的胜者组合(使用二进制枚举),对于每一种组合:
96+
- 根据当前组合确定哪些运动员获胜。
97+
- 确定当前回合中编号为 $l$ 和 $r$ 的运动员在当前回合中的位置。
98+
- 统计当前回合中编号为 $l$ 和 $r$ 的运动员在剩余运动员中的位置,记为 $a$ 和 $b$,以及剩余运动员的总数 $c$。
99+
- 递归调用 $\text{dfs}(a, b, c)$,获取当前状态的最早和最晚回合数。
100+
- 更新最早回合数和最晚回合数。
101+
6. 将计算结果存储在 $f[l][r][n]$ 中,并返回最早和最晚回合数。
102+
103+
答案为 $\text{dfs}(\text{firstPlayer} - 1, \text{secondPlayer} - 1, n)$。
86104

87105
<!-- tabs:start -->
88106

89107
#### Python3
90108

91109
```python
110+
@cache
111+
def dfs(l: int, r: int, n: int):
112+
if l + r == n - 1:
113+
return [1, 1]
114+
res = [inf, -inf]
115+
m = n >> 1
116+
for i in range(1 << m):
117+
win = [False] * n
118+
for j in range(m):
119+
if i >> j & 1:
120+
win[j] = True
121+
else:
122+
win[n - 1 - j] = True
123+
if n & 1:
124+
win[m] = True
125+
win[n - 1 - l] = win[n - 1 - r] = False
126+
win[l] = win[r] = True
127+
a = b = c = 0
128+
for j in range(n):
129+
if j == l:
130+
a = c
131+
if j == r:
132+
b = c
133+
if win[j]:
134+
c += 1
135+
x, y = dfs(a, b, c)
136+
res[0] = min(res[0], x + 1)
137+
res[1] = max(res[1], y + 1)
138+
return res
139+
140+
92141
class Solution:
93142
def earliestAndLatest(
94143
self, n: int, firstPlayer: int, secondPlayer: int
95144
) -> List[int]:
96-
# dp[i][j][k] := (earliest, latest) pair w/ firstPlayer is i-th player from
97-
# Front, secondPlayer is j-th player from end, and there're k people
98-
@functools.lru_cache(None)
99-
def dp(l: int, r: int, k: int) -> List[int]:
100-
if l == r:
101-
return [1, 1]
102-
if l > r:
103-
return dp(r, l, k)
104-
105-
a = math.inf
106-
b = -math.inf
107-
108-
# Enumerate all possible positions
109-
for i in range(1, l + 1):
110-
for j in range(l - i + 1, r - i + 1):
111-
if not l + r - k // 2 <= i + j <= (k + 1) // 2:
112-
continue
113-
x, y = dp(i, j, (k + 1) // 2)
114-
a = min(a, x + 1)
115-
b = max(b, y + 1)
116-
117-
return [a, b]
118-
119-
return dp(firstPlayer, n - secondPlayer + 1, n)
145+
return dfs(firstPlayer - 1, secondPlayer - 1, n)
146+
```
147+
148+
#### Java
149+
150+
```java
151+
class Solution {
152+
static int[][][] f = new int[30][30][31];
153+
154+
public int[] earliestAndLatest(int n, int firstPlayer, int secondPlayer) {
155+
return dfs(firstPlayer - 1, secondPlayer - 1, n);
156+
}
157+
158+
private int[] dfs(int l, int r, int n) {
159+
if (f[l][r][n] != 0) {
160+
return decode(f[l][r][n]);
161+
}
162+
if (l + r == n - 1) {
163+
f[l][r][n] = encode(1, 1);
164+
return new int[] {1, 1};
165+
}
166+
int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
167+
int m = n >> 1;
168+
for (int i = 0; i < (1 << m); i++) {
169+
boolean[] win = new boolean[n];
170+
for (int j = 0; j < m; j++) {
171+
if (((i >> j) & 1) == 1) {
172+
win[j] = true;
173+
} else {
174+
win[n - 1 - j] = true;
175+
}
176+
}
177+
if ((n & 1) == 1) {
178+
win[m] = true;
179+
}
180+
win[n - 1 - l] = win[n - 1 - r] = false;
181+
win[l] = win[r] = true;
182+
int a = 0, b = 0, c = 0;
183+
for (int j = 0; j < n; j++) {
184+
if (j == l) {
185+
a = c;
186+
}
187+
if (j == r) {
188+
b = c;
189+
}
190+
if (win[j]) {
191+
c++;
192+
}
193+
}
194+
int[] t = dfs(a, b, c);
195+
min = Math.min(min, t[0] + 1);
196+
max = Math.max(max, t[1] + 1);
197+
}
198+
f[l][r][n] = encode(min, max);
199+
return new int[] {min, max};
200+
}
201+
202+
private int encode(int x, int y) {
203+
return (x << 8) | y;
204+
}
205+
206+
private int[] decode(int val) {
207+
return new int[] {val >> 8, val & 255};
208+
}
209+
}
210+
```
211+
212+
#### C++
213+
214+
```cpp
215+
int f[30][30][31];
216+
class Solution {
217+
public:
218+
vector<int> earliestAndLatest(int n, int firstPlayer, int secondPlayer) {
219+
return dfs(firstPlayer - 1, secondPlayer - 1, n);
220+
}
221+
222+
private:
223+
vector<int> dfs(int l, int r, int n) {
224+
if (f[l][r][n] != 0) {
225+
return decode(f[l][r][n]);
226+
}
227+
if (l + r == n - 1) {
228+
f[l][r][n] = encode(1, 1);
229+
return {1, 1};
230+
}
231+
232+
int min = INT_MAX, max = INT_MIN;
233+
int m = n >> 1;
234+
235+
for (int i = 0; i < (1 << m); i++) {
236+
vector<bool> win(n, false);
237+
for (int j = 0; j < m; j++) {
238+
if ((i >> j) & 1) {
239+
win[j] = true;
240+
} else {
241+
win[n - 1 - j] = true;
242+
}
243+
}
244+
if (n & 1) {
245+
win[m] = true;
246+
}
247+
248+
win[n - 1 - l] = false;
249+
win[n - 1 - r] = false;
250+
win[l] = true;
251+
win[r] = true;
252+
253+
int a = 0, b = 0, c = 0;
254+
for (int j = 0; j < n; j++) {
255+
if (j == l) a = c;
256+
if (j == r) b = c;
257+
if (win[j]) c++;
258+
}
259+
260+
vector<int> t = dfs(a, b, c);
261+
min = std::min(min, t[0] + 1);
262+
max = std::max(max, t[1] + 1);
263+
}
264+
265+
f[l][r][n] = encode(min, max);
266+
return {min, max};
267+
}
268+
269+
int encode(int x, int y) {
270+
return (x << 8) | y;
271+
}
272+
273+
vector<int> decode(int val) {
274+
return {val >> 8, val & 255};
275+
}
276+
};
277+
```
278+
279+
#### Go
280+
281+
```go
282+
var f [30][30][31]int
283+
284+
func earliestAndLatest(n int, firstPlayer int, secondPlayer int) []int {
285+
return dfs(firstPlayer-1, secondPlayer-1, n)
286+
}
287+
288+
func dfs(l, r, n int) []int {
289+
if f[l][r][n] != 0 {
290+
return decode(f[l][r][n])
291+
}
292+
if l+r == n-1 {
293+
f[l][r][n] = encode(1, 1)
294+
return []int{1, 1}
295+
}
296+
297+
min, max := 1<<30, -1<<31
298+
m := n >> 1
299+
300+
for i := 0; i < (1 << m); i++ {
301+
win := make([]bool, n)
302+
for j := 0; j < m; j++ {
303+
if (i>>j)&1 == 1 {
304+
win[j] = true
305+
} else {
306+
win[n-1-j] = true
307+
}
308+
}
309+
if n&1 == 1 {
310+
win[m] = true
311+
}
312+
win[n-1-l] = false
313+
win[n-1-r] = false
314+
win[l] = true
315+
win[r] = true
316+
317+
a, b, c := 0, 0, 0
318+
for j := 0; j < n; j++ {
319+
if j == l {
320+
a = c
321+
}
322+
if j == r {
323+
b = c
324+
}
325+
if win[j] {
326+
c++
327+
}
328+
}
329+
330+
t := dfs(a, b, c)
331+
if t[0]+1 < min {
332+
min = t[0] + 1
333+
}
334+
if t[1]+1 > max {
335+
max = t[1] + 1
336+
}
337+
}
338+
339+
f[l][r][n] = encode(min, max)
340+
return []int{min, max}
341+
}
342+
343+
func encode(x, y int) int {
344+
return (x << 8) | y
345+
}
346+
347+
func decode(val int) []int {
348+
return []int{val >> 8, val & 255}
349+
}
350+
```
351+
352+
#### TypeScript
353+
354+
```ts
355+
function earliestAndLatest(n: number, firstPlayer: number, secondPlayer: number): number[] {
356+
return dfs(firstPlayer - 1, secondPlayer - 1, n);
357+
}
358+
359+
const f: number[][][] = Array.from({ length: 30 }, () =>
360+
Array.from({ length: 30 }, () => Array(31).fill(0)),
361+
);
362+
363+
function dfs(l: number, r: number, n: number): number[] {
364+
if (f[l][r][n] !== 0) {
365+
return decode(f[l][r][n]);
366+
}
367+
if (l + r === n - 1) {
368+
f[l][r][n] = encode(1, 1);
369+
return [1, 1];
370+
}
371+
372+
let min = Number.MAX_SAFE_INTEGER;
373+
let max = Number.MIN_SAFE_INTEGER;
374+
const m = n >> 1;
375+
376+
for (let i = 0; i < 1 << m; i++) {
377+
const win: boolean[] = Array(n).fill(false);
378+
for (let j = 0; j < m; j++) {
379+
if ((i >> j) & 1) {
380+
win[j] = true;
381+
} else {
382+
win[n - 1 - j] = true;
383+
}
384+
}
385+
386+
if (n & 1) {
387+
win[m] = true;
388+
}
389+
390+
win[n - 1 - l] = false;
391+
win[n - 1 - r] = false;
392+
win[l] = true;
393+
win[r] = true;
394+
395+
let a = 0,
396+
b = 0,
397+
c = 0;
398+
for (let j = 0; j < n; j++) {
399+
if (j === l) a = c;
400+
if (j === r) b = c;
401+
if (win[j]) c++;
402+
}
403+
404+
const t = dfs(a, b, c);
405+
min = Math.min(min, t[0] + 1);
406+
max = Math.max(max, t[1] + 1);
407+
}
408+
409+
f[l][r][n] = encode(min, max);
410+
return [min, max];
411+
}
412+
413+
function encode(x: number, y: number): number {
414+
return (x << 8) | y;
415+
}
416+
417+
function decode(val: number): number[] {
418+
return [val >> 8, val & 255];
419+
}
120420
```
121421

122422
<!-- tabs:end -->

0 commit comments

Comments
 (0)