博弈论_基础

博弈论

定义:有若干个人进行博弈,每人轮流操作,且每个人的每一步都是最正确的操作,问什么时候必败/必胜

模型:

建模

①设先手必胜局面为 N N N,先手必败局面为 P P P,于是就有了一些结论

  1. 如果当前局面为 N N N,那么它肯定变化成 P P P,因为我们要必胜,那么对手必须进入一先手必败的 P P P中,于是 N N N必定能变化成 P P P
  2. 同理,一个 P P P肯定能变化成 N N N

②于是我们就可以开始建图了

  1. 设每一个状态都为一个节点,我们就可以从当前节点像每一个能到达的点,连一条有向边
  2. 于是我们已知游戏结束的状态是 P P P,然后从这个状态扩展出去,如果一个节点能到底 P P P那么它就是 N N N, 如果能到到达的每一个点都是 N N N,即不能到底 P P P,那么则为 P P P
    ③我们的博弈论基本模型就建好了,其实每一个博弈论问题都可以转换为一个 D A G DAG DAG

S G SG SG定理和 S G SG SG函数

m e x mex mex运算:

对于一个集合 S S S,它的 m e x ( S ) mex(S) mex(S)就为最小的、不属于集合 S S S的非负整数

S G ( x ) SG(x) SG(x)

对于 S G ( x ) SG(x) SG(x),有 S G ( x ) = m e x ( S G ( y ) , < x , y > ∈ E ) SG(x)=mex(SG(y),<x,y>∈E) SG(x)=mex(SG(y),<x,y>E),其实就是它在 D A G DAG DAG图中所有后继状态的 m e x mex mex

S G ( x ) SG(x) SG(x)的拆分

如果 x x x可以拆分成互不影响的几个子游戏 x 1 , x 2 , . . . x n x_1,x_2,...x_n x1,x2,...xn,那么 S G ( x ) = S G ( x 1 ) ⊕ S G ( x 2 ) ⊕ . . . ⊕ S G ( x n ) SG(x)=SG(x_1)⊕SG(x_2)⊕...⊕SG(x_n) SG(x)=SG(x1)SG(x2)...SG(xn)

S G ( x ) SG(x) SG(x)与胜负

S G ( x ) = 0 SG(x)=0 SG(x)=0为先手必败,否则先手必胜


常见模型

巴什博奕( B a s h G a m e Bash Game BashGame

题目大意:有 n n n个石子,每次少取 1 1 1个,最多取 m m m个,问先手必胜还是必败
分析:(正常分析)
  1. 假设我们面对了一个 ( m + 1 ) ∣ n (m+1)|n (m+1)n的情况,那么假设我们取了 x x x个,那么对手肯定能取 m + 1 − x m+1-x m+1x个,使得对手 + + +我们的和为 m + 1 m+1 m+1,因为 ( m + 1 ) ∣ n (m+1)|n (m+1)n,所以对手肯定能取到最后一个,所以当 ( m + 1 ) ∣ n (m+1)|n (m+1)n时,先手必败
  2. 同理如果 ( m + 1 ) ∤ n (m+1) \nmid n (m+1)n,则我们可以先取走 n % ( m + 1 ) n\%(m+1) n%(m+1)个,使得对手面临 ( m + 1 ) ∣ n (m+1)|n (m+1)n,那么这时先手必胜
代码实现:
#include<bits/stdc++.h>
using namespace std;
int t;
int main()
{
	cin >> t;
	while (t--)
	{
		int n,k;cin >> n >> k;
		if (n%(k+1)==0) printf("B\n");
		else printf("A\n");	
	}	
}

威佐夫博弈( W y t h o f f G a m e Wythoff Game WythoffGame

题目大意:有两堆石头,数量分别为 n , m n,m n,m,每次可以在一堆,或者两堆中,同时取任意个石头,不能不取,问先手必胜还是必败
分析:(打标,找规律)
  1. 我们列举前几个先手必败的情况看一些, ( 0 , 0 ) , ( 1 , 2 ) , ( 3 , 5 ) , ( 4 , 7 ) , ( 6 , 10 ) . . . (0,0),(1,2),(3,5),(4,7),(6,10)... (0,0),(1,2),(3,5),(4,7),(6,10)...,对于以 n n n排序之后的数对,我们发现 n i n_i ni为之前所有数对中未出现的最小自然数, m i m_i mi n i + i − 1 n_i+i-1 ni+i1,
  2. 其实我们就可以暴力算出当前局面是什么了,但有大佬又证明出了,每个先手必败的局面的数对都是 ( [ i × ϕ ] , [ i × ϕ 2 ] ) ([i×ϕ],[i×ϕ^2]) ([i×ϕ],[i×ϕ2]) ϕ = 5 − 1 2 ϕ=\frac{\sqrt5-1}{2} ϕ=25 1证明)(%%%
代码实现:
#include<iostream>
#include<cmath>
using namespace std;
const double phi=(sqrt(5)+1)/2;
int a,b,t;
int main()
{
	cin >> t;
	ios::sync_with_stdio(false);
	while (t--)
	{
		cin >> a >> b;
		if (a>b) swap(a,b);
		int A=abs(a-b)*phi;
		if (A==a) cout << "B"<< endl;
		else cout << "A" << endl;
	}
	return 0;
}

尼姆博弈( N i m G a m e Nim Game NimGame)

题目大意:有 n n n堆石子,每堆石子有 A i A_i Ai个石子,两个人轮流操作,每次从一堆石子中,取任意个,不能不取,问先手必胜还是必败
分析:
  1. A 1 ⊕ A 2 ⊕ . . . ⊕ A n ≠ 0 A_1 ⊕ A_2 ⊕ ... ⊕ A_n\not=0 A1A2...An=0,那么必然有 A i ⩾ x A_i \geqslant x Aix(异或的性质),所有说只要将 A i A_i Ai减成 x x x,那么就可以使得 A 1 ⊕ A 2 ⊕ . . . ⊕ A n = 0 A_1 ⊕ A_2 ⊕ ... ⊕ A_n=0 A1A2...An=0,于是一个异或和不为 0 0 0的一定可以到底一个异或和为 0 0 0
  2. A 1 ⊕ A 2 ⊕ . . . ⊕ A n = 0 A_1 ⊕ A_2 ⊕ ... ⊕ A_n=0 A1A2...An=0,如果可以将 A i A_i Ai变成 A i ′ A_i^{'} Ai使得 A 1 ⊕ A 2 ⊕ . . . ⊕ A n ≠ 0 A_1 ⊕ A_2 ⊕ ... ⊕ A_n\not=0 A1A2...An=0,那么将两个式子异或,得到 A i ⊕ A i ′ = 0 , A i = A i ′ A_i ⊕ A_i^{'}=0,A_i=A_i^{'} AiAi=0,Ai=Ai,矛盾,所以异或和为 0 0 0的一定不可以保持异或和为 0 0 0
  3. 因为所有石子都被取完时为 P P P,而且石头是不断减少的,所以当异或和为 0 0 0是先手必败,否则先手必胜
代码实现:
#include<bits/stdc++.h>
using namespace std;
int a[10010],n,t;
int main()
{
	cin >> t;
	while (t--)
	{
		int ans;
		cin >> n;
		for (int i=1;i<=n;i++) cin >> a[i];
		ans=a[1];
		for (int i=2;i<=n;i++) ans=ans^a[i];
		if (ans==0) printf("No\n");
		else printf("Yes\n"); 
	}
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值