@@ -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+
92141class 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