|
|
|
@ -110,68 +110,70 @@ $\large L[i][i]=R[i][i]=a_i$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### 分类讨论
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- **特殊情况:$L=R=0$**
|
|
|
|
|
|
|
|
|
|
令 $\displaystyle \large x=a[j](x>0)$
|
|
|
|
|
令 $\displaystyle \large X=a[j](x>0)$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
若 $R=0$ 则 $L=R=0$,此时 $x>\max\{L,R\}$,也就是说 $L=0$ 和 $R=0$ 都属于 $Case$ $5$,故其它 $Case$ 满足 $L,R>0$。
|
|
|
|
|
|
|
|
|
|
> <font color='red'><b>注:因$R=0$,表示在[$i$,$j-1$]确定后,右侧为$0$就能满足[$i$,$j-1$]这一段为先手必败,此时,左侧增加那堆个数为$0$就可以继续保持原来的先手必败,即$L=0$,而且已经证明了$L=R=0$是唯一的。</b></font>
|
|
|
|
|
|
|
|
|
|
* $x=R$($Case$ $1$)
|
|
|
|
|
最简单的情况——根据 $R=right[i][j-1]$ 的定义,$x=R$则区间 $[i,j]$ 是必败局面,因此左边啥也不能添,添了反而错,故
|
|
|
|
|
* $X=R$($Case$ $1$)
|
|
|
|
|
最简单的情况——根据 $R=right[i][j-1]$ 的定义,$X=R$则区间 $[i,j]$ 是必败局面,因此左边啥也不能添,添了反而错,故
|
|
|
|
|
$$\large left[i][j]=0$$
|
|
|
|
|
|
|
|
|
|
* $x<R$
|
|
|
|
|
* $x<L$,即 $x< \min\{L,R\}$($Case$ $2$)
|
|
|
|
|
* $X<R$
|
|
|
|
|
* ① $X<L$,即 $X< \min\{L,R\}$($Case$ $2$)
|
|
|
|
|
* **结论**:
|
|
|
|
|
$$\large left[i][j]=x$$
|
|
|
|
|
$$\large left[i][j]=X$$
|
|
|
|
|
* **证明**:
|
|
|
|
|
即 **求证** $\large (x,a_i,a_{i+1},\cdots,a_{j-1},x)$为必败局面,其中$x< \min\{L,R\}$
|
|
|
|
|
即 **求证** $\large (X,a_i,a_{i+1},\cdots,a_{j-1},X)$为必败局面,其中$X< \min\{L,R\}$
|
|
|
|
|
|
|
|
|
|
由于最左边和最右边的两堆石子数量相同,后手可进行和先手 **对称** 操作,后手必将获得一个形如$(y,a_i,a_{i+1},⋯,a_{j−1})$ 或 $(a_i,a_{i+1},\cdots,a_{j-1},y)$ 的局面,其中: $0<y < x<\min\{L,R\}$
|
|
|
|
|
由于最左边和最右边的两堆石子数量相同,后手可进行和先手 **对称** 操作,后手必将获得一个形如$(y,a_i,a_{i+1},⋯,a_{j−1})$ 或 $(a_i,a_{i+1},\cdots,a_{j-1},y)$ 的局面,其中: $0<y < X<\min\{L,R\}$
|
|
|
|
|
|
|
|
|
|
**只有左侧为$L=left(i,j-1)$这个唯一值时,才是必败态,现在不是$L$,而是$y<min(L,R)$,所以后手必胜,即先手必败**, **证毕**。
|
|
|
|
|
|
|
|
|
|
<br>
|
|
|
|
|
|
|
|
|
|
* $x \geq L$,即 $L \leq x < R$($Case$ $3$)
|
|
|
|
|
* **结论**:$$\large left[i][j]=x+1$$
|
|
|
|
|
* ② $X \geq L$,即 $L \leq X < R$($Case$ $3$)
|
|
|
|
|
* **结论**:$$\large left[i][j]=X+1$$
|
|
|
|
|
* **证明**:
|
|
|
|
|
即 **求证** $(x+1,a_i,a_{i+1},\cdots,a_{j-1},x)$为 **必败局面** ,其中 $L \leq x <R$
|
|
|
|
|
即 **求证** $(X+1,a_i,a_{i+1},\cdots,a_{j-1},X)$为 **必败局面** ,其中 $L \leq X <R$
|
|
|
|
|
|
|
|
|
|
* 若先手拿最左边一堆,设拿了以后 **还剩 $z$ 个石子**
|
|
|
|
|
* 若 $z>L$,则后手将最右堆拿成 $z-1$ 个石子($z-1 \ge L>0$),**保证左侧比右侧多$1$个石子**,就能回到 $Case$ $3$ 本身,递归证明即可
|
|
|
|
|
* 若 $z=L$,则后手将最右堆拿完,根据 $L=left[i][j-1]$ 定义知此时局面必败
|
|
|
|
|
* 若 $0<z<L$,则后手将最右堆拿成 $z$ 个石子,**由 $Case$ $2$ 知此时是必败局面**
|
|
|
|
|
* 若 $z=0$,此时最右堆石子数 $x$ 满足 $L \le x<R$,结合 $right[i][j-1]$ 定义知 **此局面必胜**
|
|
|
|
|
* 若 $z=0$,此时最右堆石子数 $X$ 满足 $L \le X<R$,结合 $right[i][j-1]$ 定义知 **此局面后手必胜,也就是先手必败**
|
|
|
|
|
<br>
|
|
|
|
|
* 若先手拿最右边一堆,设拿了以后 **还剩 $z$ 个石子**
|
|
|
|
|
* 若 $z \ge L$,则后手将最左堆拿成 $z+1$个石子,就能回到 $Case$ $3$ 本身,递归证明即可
|
|
|
|
|
* 若 $0<z<L$,则后手将最左堆拿成 $z$ 个石子,**由 $Case$ $2$ 知此时是必败局面**
|
|
|
|
|
* 若 $z=0$,则后手将最左堆拿成 $L$ 个石子,由 $left[i][j-1]$定义知此时局面必败
|
|
|
|
|
* 若 $z=0$,则后手将最左堆拿成 $L$ 个石子,由 $left[i][j-1]$定义知此时局面先手必败
|
|
|
|
|
|
|
|
|
|
* $x>R$
|
|
|
|
|
* $x≤L$,即 $R < x \leq L$($Case$ $4$)
|
|
|
|
|
* 结论:$$\large left[i][j]=x-1$$
|
|
|
|
|
* $X>R$
|
|
|
|
|
* ① $X≤L$,即 $R < X \leq L$($Case$ $4$)
|
|
|
|
|
* 结论:$$\large left[i][j]=X-1$$
|
|
|
|
|
* **证明**:
|
|
|
|
|
* 若先手拿最左边一堆,设拿了以后还剩 $z$ 个石子。
|
|
|
|
|
* 若 $z \geq R$,则后手将最右堆拿成 $z+1$ 个石子,<font color='red' size=4><b>保证左侧比右侧多$1$个石子</b></font>,就能回到 $Case$ $4$ 本身,递归证明即可。
|
|
|
|
|
* 若 $z \geq R$,则后手将最右堆拿成 $z+1$ 个石子,<b>保证左侧比右侧多$1$个石子</b>,就能回到 $Case$ $4$ 本身,递归证明即可。
|
|
|
|
|
* 若 $0<z<R$,则后手将最右堆拿成 $z$ 个石子,由 $Case$ $2$ 知此时是必败局面。
|
|
|
|
|
* 若 $z=0$,则后手将最右堆拿成 $R$ 个石子(注意 $Case$ $4$ 保证了此时最右堆石子个数 $>R$),由 $right[i][j-1])$ 的定义知此时是必败局面。
|
|
|
|
|
|
|
|
|
|
<br>
|
|
|
|
|
|
|
|
|
|
* 若先手拿最右边一堆,设拿了以后还剩 $z$ 个石子。
|
|
|
|
|
* 若 $z>R$,则后手将最左边一堆拿成 $z-1$ 个石子(注意 $z-1 \ge R >0$),递归证明即可。<font color='red' size=4><b>保证右侧比左侧多$1$个石子。</b></font>
|
|
|
|
|
* 若 $z>R$,则后手将最左边一堆拿成 $z-1$ 个石子(注意 $z-1 \ge R >0$),递归证明即可。<b>保证右侧比左侧多$1$个石子。</b>
|
|
|
|
|
* 若 $z=R$,则后手把最左堆拿完,根据 $right[i][j-1]$的定义可知得到了必败局面。
|
|
|
|
|
* 若 $0<z<R$,则后手将最左堆拿成 $z$ 个石子,由 $Case$ $2$ 知此时是必败局面。
|
|
|
|
|
* 若 $z=0$,此时最左堆石子数量 $k$ 满足 $0<k<L$,结合 $left[i][j-1]$ 定义知局面必胜
|
|
|
|
|
<br>
|
|
|
|
|
|
|
|
|
|
* $x>L$,即 $x>\max\{L,R\}$($Case$ $5$)
|
|
|
|
|
* ② $X>L$,即 $X>\max\{L,R\}$($Case$ $5$)
|
|
|
|
|
* **结论**:$$\large left[i][j]=x$$
|
|
|
|
|
* **证明**:
|
|
|
|
|
设先手将其中一堆拿成了 $z$ 个石子。
|
|
|
|
@ -190,30 +192,30 @@ $\large L[i][i]=R[i][i]=a_i$
|
|
|
|
|
|
|
|
|
|
**综上所述:**
|
|
|
|
|
$$ \large
|
|
|
|
|
L[i][j]=
|
|
|
|
|
left[i][j]=
|
|
|
|
|
\large \left\{\begin{matrix}
|
|
|
|
|
0 & x=R \\
|
|
|
|
|
x+1&L \leq x < R \\
|
|
|
|
|
x-1 & R<x \leq L \\
|
|
|
|
|
x & otherwise
|
|
|
|
|
0 & X=R \\
|
|
|
|
|
X+1&L \leq X < R \\
|
|
|
|
|
X-1 & R<X \leq L \\
|
|
|
|
|
X & otherwise
|
|
|
|
|
\end{matrix}\right.
|
|
|
|
|
$$
|
|
|
|
|
|
|
|
|
|
<font color='blue' size=4><b>温馨提示:</b></font>**请看清楚 $L$ 取不取等,乱取等是错的!**
|
|
|
|
|
|
|
|
|
|
同理可求 $R(i,j)$。
|
|
|
|
|
> <font color='blue' size=4><b>温馨提示:</b></font>**请看清楚 $L$ 取不取等,乱取等是错的!**
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
时间复杂度 $O(n^2)$。
|
|
|
|
|
同理可求 $right(i,j)$。
|
|
|
|
|
|
|
|
|
|
### 六、实现代码
|
|
|
|
|
```cpp {.line-numbers}
|
|
|
|
|
#include <cstdio>
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
const int N = 1010;
|
|
|
|
|
|
|
|
|
|
int n;
|
|
|
|
|
int a[N], l[N][N], r[N][N];
|
|
|
|
|
int a[N];
|
|
|
|
|
int left[N][N], right[N][N];
|
|
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
|
int T;
|
|
|
|
@ -226,37 +228,37 @@ int main() {
|
|
|
|
|
for (int i = 1; i + len - 1 <= n; i++) {
|
|
|
|
|
int j = i + len - 1;
|
|
|
|
|
if (len == 1)
|
|
|
|
|
l[i][j] = r[i][j] = a[i];
|
|
|
|
|
left[i][j] = right[i][j] = a[i];
|
|
|
|
|
else {
|
|
|
|
|
int L = l[i][j - 1], R = r[i][j - 1], x = a[j];
|
|
|
|
|
if (R == x)
|
|
|
|
|
l[i][j] = 0;
|
|
|
|
|
else if (x < L && x < R || x > L && x > R)
|
|
|
|
|
l[i][j] = x;
|
|
|
|
|
int L = left[i][j - 1], R = right[i][j - 1], X = a[j];
|
|
|
|
|
if (R == X)
|
|
|
|
|
left[i][j] = 0;
|
|
|
|
|
else if (X < L && X < R || X > L && X > R)
|
|
|
|
|
left[i][j] = X;
|
|
|
|
|
else if (L > R)
|
|
|
|
|
l[i][j] = x - 1;
|
|
|
|
|
left[i][j] = X - 1;
|
|
|
|
|
else
|
|
|
|
|
l[i][j] = x + 1;
|
|
|
|
|
|
|
|
|
|
// 与上述情况对称的四种情况
|
|
|
|
|
L = l[i + 1][j], R = r[i + 1][j], x = a[i];
|
|
|
|
|
if (L == x)
|
|
|
|
|
r[i][j] = 0;
|
|
|
|
|
else if (x < L && x < R || x > L && x > R)
|
|
|
|
|
r[i][j] = x;
|
|
|
|
|
left[i][j] = X + 1;
|
|
|
|
|
|
|
|
|
|
L = left[i + 1][j], R = right[i + 1][j], X = a[i];
|
|
|
|
|
if (L == X)
|
|
|
|
|
right[i][j] = 0;
|
|
|
|
|
else if (X < L && X < R || X > L && X > R)
|
|
|
|
|
right[i][j] = X;
|
|
|
|
|
else if (R > L)
|
|
|
|
|
r[i][j] = x - 1;
|
|
|
|
|
right[i][j] = X - 1;
|
|
|
|
|
else
|
|
|
|
|
r[i][j] = x + 1;
|
|
|
|
|
right[i][j] = X + 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (n == 1)
|
|
|
|
|
puts("1");
|
|
|
|
|
else
|
|
|
|
|
printf("%d\n", l[2][n] != a[1]);
|
|
|
|
|
printf("%d\n", left[2][n] != a[1]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
```
|