其他分享
首页 > 其他分享> > Cutting Game(Grundy值)

Cutting Game(Grundy值)

作者:互联网




在这里插入图片描述

就记住了一句话,对于分割问题,分割后各部分Grundy值异或后的值等于分割前的Grundy值

#pragma GCC optimize(2)
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
#define pi acos(-1.0)
#define e exp(1.0)
const ll maxn=300;
ll w,h;
ll mem[maxn][maxn];//记录Grundy值
//用记忆化搜索计算Grundy值 
ll Grundy(ll w,ll h)
{
	if(mem[w][h]!=-1)
	return mem[w][h];
	set<int>s;
	for(ll i=2;w-i>=2;i++)
	s.insert(Grundy(i,h)^Grundy(w-i,h));
	for(ll i=2;h-i>=2;i++)
	s.insert(Grundy(w,i)^Grundy(w,h-i));
	ll g=0;
	while(s.count(g)!=0) g++;
	return mem[w][h]=g;
} 
int main()
{
//  freopen(".../.txt","w",stdout);
	ios::sync_with_stdio(false);
	cin>>w>>h;
	memset(mem,-1,sizeof(mem));
	ll jie=Grundy(w,h);
	if(jie)
	puts("Win");
	else
	puts("Lose");
	return 0;
}
我开始有个疑问:为什么求Grundy值的函数中两层for循环要保证被被分割后的图形的长宽一定要大于等于2呢?结合后面的代码我是这样理解的,那两层for循环是判断当前状态是否可能是必胜态,既然是判断必胜态,肯定是从有可能的状态进行判断,而一旦分割出了长或宽为1的情况,那就一定是必败态了,所以不能考虑这种情况,必须得从长宽大于等于2来判断。如果当前状态的Grundy值是0,那就是必败态,否则即为必胜态
嘘……一只bug 发布了50 篇原创文章 · 获赞 4 · 访问量 931 私信 关注

标签:分割,return,mem,ll,++,Game,Cutting,Grundy
来源: https://blog.csdn.net/weixin_43311695/article/details/104582715