博弈论的Nim值和Grundy数解析

概要

博弈论好有意思感觉以后可以用这招坑人了。。。。。。

思想本质其实还是贪心了,万法归贪嘛
首先是对于动态规划的贪心,但是限制比较大

void solve(){
	win[0]=false;
	//当轮到自己时没有硬币了,那么就是必输态
	for(int j=1;j<=X;j++){
		win[j]=false;
		for(int i=0;i<K;i++){
			//如果让对手达到必输态,那么我们就是必赢态了
			win[j]|=A[i]<=j&&!win[j-A[i]]; 
		}
	} 
} 

对于高级”奇偶“的贪心(POJ 2484)
其实规则都可以转化成:
存在一堆石子,先手拿一个,后手拿一个,最后看看谁能拿到最后一个
这样奇偶性就能决定胜利与失败了
就如同 这个题:
A Funny Game
最终的策略就是你拿一个我也拿一个为最优策略,其实思路还要复杂一点但是问题本质还是奇偶问题(谁能将数据变为偶数谁就能必胜)

Nim值解析

首先该值使用了异或这个运算符,二进制中相同取0不同取1

a1^ a2 ^a3 ^…, ^an=0时 先手必输反之先手必赢
这是为什么呢?
因为若Nim为0,说明每一个二进制的1都有偶数个,所以无论先手取多少后手都可以取相同的个数,导致变为你拿一个我也拿一个的局势导致谁能维持偶数形式谁就赢。

Grundy数解析

其实Grundy数本质还是Nim的应用,最后还是要异或求Nim值
具体思路就是将抽象的数据,转化为可以使用异或计算的数值
对比:
Nim中有x颗石子的石子堆,能够转移成0,1,…,x-1
从Grundy值为x的状态出发,可以转移到Grundy值为0,1,…,x-1的状态

通俗理解就是Nim是可以取任意数量的石子从而可以使石子堆变为任意小于本身总量的x‘
但是Grundy值就是将石子堆本身具有的sum总量变为可以任意变化的x形式
于是转化算法如下

void solve(){
	//0与0没区别 
	grundy[0]=0;
	//计算grundy值
	int max_x=*max_element(x,x+n);//找出石子堆的最大值
	for(int j=1;j<=max_x;j++){
		set<int>s;
		for(int i=0;i<k;i++){
			if(A[i]<=j)s.insert(grundy[j-A[i]]);//收集可以变化的数字 
		}
		int g=0;
		while(s.count(g)!=0)g++;
		//计算能达到的等价x(要求操作后可以使该堆石子能变化为小于x的任意数字) 
		grundy[j]=g;
	
	}
	//使用Nim值判断胜负
	int x1=0;
	for(int i=0;i<N;i++)x1^=grundy[x[i]];
	 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值