博弈论
博弈论基础介绍:
巴什博弈:
例子:
一堆石子 \(n\) 个,任意取 \([1-m]\) 个,问先手必赢/输。
分析:
分类进行考虑:
- \([1,m]\) 个,先手必赢。
- \(m+1\) 个,先手必输。
- \([m+2,2m]\) 先手可以拿走几个,剩下 \(m+1\) 个,先手必胜。
我们发现,面临 \(m+1\) 个石子的人一定失败。
进行推广:设当前石子数为 \(n=k*(m+1)+r\), 先手先拿走 \(r\) 个,无论后手怎么拿 \(x\) 个,先手一定可以拿走 \(m+1-x\) 个,这样后手一定失败。
反之,当 \((m+1)|n\) ,先手一定失败。
因此,只要不满足 \((m+1)|n\) ,就一定先手必胜,反之必败,直接判断即可。
\(nim\) 游戏
例子:
有 \(n\) 堆石子,两个人可以从任意一堆石子中拿任意多个石子(不能不拿),没法拿的人失败。问谁会胜利。
定理:
当 \(n\) 堆石子的数量异或和等于 \(0\) 时,先手必败,否则先手必胜.
证明:
必败状态:我们设 \(a[i]\) 表示 \(i\) 堆石子的数量。当前局面为:
\[0⊕0⊕0⊕⋯⊕0=0
\]
对于先手来说,如果当前局面为:
\[a_1⊕a_2⊕a_3⊕⋯⊕a_n=k
\]
那么一定存在 \(a_i\) ,二进制表示在最高位 \(k\) 上为 \(1\)。
我们将 \(a_i⊕k\) ,这样就变成了:
\[a_1⊕a_2⊕a_3⊕⋯⊕a_n⊕k=0
\]
我们只需要保证给后手的人所有石子异或值为0,即可获胜,此时先手必胜。
反之,一开始异或值为 \(0\) ,此时先手必败。
特殊情况:
有些题目,只能选择 \([1-m]\) 个石子,这就是 \(nim+bash\) ,只需要将所有的石子堆的石子数目同时模 \(m+1\),然后异或运算即可。
for(int i=1;i<=N;i++) scanf("%d",&a[i]);
for(int i=1;i<=N;i++) ans=ans^a[i];
ans==0?printf("No\n"):printf("Yes\n");
不关注的有难了😠😠😠https://b23.tv/hoXKV9

浙公网安备 33010602011771号